denki_guy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.markdown ADDED
@@ -0,0 +1,47 @@
1
+ Denki Guy
2
+ =========
3
+
4
+ Denki Guy (電気ガイ) is an electrician who will rig up all of the houses in the buroughs of your denkigai (電気街), the electric town... Akihabara.
5
+
6
+ What is it really?
7
+
8
+ It is a small framework based on the akihabara html5 gaming engine with rails developers in mind. The emphasis is less on a rich gaming experience and more on easily generating a 2d top-down jrpg style map for players to explore. A lot was cut from the original framework, and entrances to other pages (which actually require a new url) were added to enable a new take on the familiar paradigm of content + links.
9
+
10
+ Dependencies
11
+ ------
12
+ * rails 3
13
+ * jquery
14
+
15
+ Setup
16
+ --------------------
17
+ 1. Copy this entire directory into your_project/lib/generators directory
18
+ 2. rails generate rpg <whatever_you_want_the_map_to_be_called>
19
+ 3. Add in the jquery javascript file in application.rb like so:
20
+ <%= javascript_include_tag 'jquery' %>
21
+
22
+ Usage
23
+ ----
24
+ * A route will be created at whatever you used for the map name (/map_name) Visiting this will give you a pretty good idea of what the generator created
25
+ * To customize the sprites available, you will want to edit the images at public/images/game/ (by the way: denki guy doesn't have its own image editor. It's photoshop or pixen to the rescue)
26
+ * To change what sprites are used in the game, public/javascripts/game/resources.js is your friend
27
+ * To change how npcs (and their dialogues) and other large objects such as the house would be added, edit public/javascripts/game/<your_map>/<your_map>_npc.js
28
+ * To change how the less consequential sprites are added to the map, edit public/javascripts/game/<your_map>/<your_map>_map.js
29
+ * To see a handful of other setting for your map, look at public/javascripts/game/<your_map>/<your_map>_settings.js
30
+
31
+ Future Features
32
+ -----------
33
+ * Additional map types that can be autogenerated
34
+ * A standard way of laying out sprites in an image file. If this was realized, players could take their avatars with them from one denki guy site to another.
35
+ * A menuing extension of the dialogue system that will support decision trees, or even an interaction as complicated buying something from the ubiquitous "shops" that pepper old jrpgs
36
+ * An inventory system that uses cookies and/or a database to store an inventory, preferences, avatars, etc.
37
+ * Text input for less one sided conversations
38
+ * Internationalization in dialogues
39
+ * Akihabara reintegration to support more sophisticated npcs, weapons, hud, audio, and non-rpg style games
40
+ * Remove reliance on jquery
41
+ * A text parser that will automatically generate text to be formatted for dialogues
42
+
43
+ If you have any patches, sprites or other ideas to share, I would love to hear them!
44
+
45
+ Cheers,
46
+
47
+ -Evan
data/lib/USAGE ADDED
@@ -0,0 +1,35 @@
1
+ Description:
2
+ This generator creates an rpg style html5 game with one map. The engine is based on the akihabara engine
3
+
4
+ Example:
5
+ rails generate rpg my_map
6
+
7
+ This will create:
8
+ create app/views/game/my_map.html.erb
9
+ create app/controllers/game_controller.rb
10
+ create public/javascripts/game/akihabara/gamecycle.js
11
+ create public/javascripts/game/akihabara/gbox.js
12
+ create public/javascripts/game/akihabara/help.js
13
+ create public/javascripts/game/akihabara/iphopad.js
14
+ create public/javascripts/game/akihabara/tool.js
15
+ create public/javascripts/game/akihabara/toys.js
16
+ create public/javascripts/game/akihabara/trigo.js
17
+ create public/javascripts/game/game.js
18
+ create public/javascripts/game/init_game.js
19
+ create public/javascripts/game/resources.js
20
+ create public/javascripts/game/my_map/my_map.js
21
+ create public/javascripts/game/my_map/my_map.js
22
+ create public/javascripts/game/my_map/my_map.js
23
+ create public/javascripts/game/my_map/my_map.js
24
+ create public/images/game/font.png
25
+ create public/images/game/cels.png
26
+ create public/images/game/akihabara/8x8s.png
27
+ create public/images/game/akihabara/buttons.png
28
+ create public/images/game/akihabara/debugfont.png
29
+ create public/images/game/akihabara/dpad.png
30
+ create public/images/game/akihabara/dpad320.png
31
+ create public/images/game/akihabara/fontbig.png
32
+ create public/images/game/akihabara/padbg.png
33
+ route match 'my_map' => 'game#my_map', :as => 'my_map'
34
+ create public/javascripts/jquery.js
35
+
@@ -0,0 +1,103 @@
1
+ class RpgGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path("../templates", __FILE__)
3
+
4
+ def create_html_file
5
+ create_file "app/views/game/#{file_name}.html.erb" do
6
+ " <%= javascript_include_tag 'game/#{file_name}/#{file_name}_settings' %>
7
+ <%= javascript_include_tag 'game/akihabara/gbox' %>
8
+ <%= javascript_include_tag 'game/akihabara/iphopad' %>
9
+ <%= javascript_include_tag 'game/akihabara/trigo' %>
10
+ <%= javascript_include_tag 'game/akihabara/toys' %>
11
+ <%= javascript_include_tag 'game/akihabara/help' %>
12
+ <%= javascript_include_tag 'game/akihabara/tool' %>
13
+ <%= javascript_include_tag 'game/akihabara/gamecycle' %>
14
+
15
+ <%= javascript_include_tag 'game/resources' %>
16
+ <%= javascript_include_tag 'game/#{file_name}/#{file_name}_map' %>
17
+ <%= javascript_include_tag 'game/#{file_name}/#{file_name}_npc' %>
18
+ <%= javascript_include_tag 'game/init_game' %>
19
+ <%= javascript_include_tag 'game/#{file_name}/#{file_name}' %>
20
+ <%= javascript_include_tag 'game/game' %>
21
+ "
22
+ end
23
+ end
24
+
25
+ def create_game_controller
26
+ copy_file "game_controller.rb", "app/controllers/game_controller.rb"
27
+ end
28
+
29
+ def include_akihabara_framework
30
+ copy_file "gamecycle.js", "public/javascripts/game/akihabara/gamecycle.js"
31
+ copy_file "gbox.js", "public/javascripts/game/akihabara/gbox.js"
32
+ copy_file "help.js", "public/javascripts/game/akihabara/help.js"
33
+ copy_file "iphopad.js", "public/javascripts/game/akihabara/iphopad.js"
34
+ copy_file "tool.js", "public/javascripts/game/akihabara/tool.js"
35
+ copy_file "toys.js", "public/javascripts/game/akihabara/toys.js"
36
+ copy_file "trigo.js", "public/javascripts/game/akihabara/trigo.js"
37
+ end
38
+
39
+ def create_game_javascripts
40
+ copy_file "game.js", "public/javascripts/game/game.js"
41
+ copy_file "init_game.js", "public/javascripts/game/init_game.js"
42
+ copy_file "resources.js", "public/javascripts/game/resources.js"
43
+ end
44
+
45
+ def create_level_javascripts
46
+ copy_file "level_template.js", "public/javascripts/game/#{file_name}/#{file_name}.js"
47
+ copy_file "map_template.js", "public/javascripts/game/#{file_name}/#{file_name}_map.js"
48
+ copy_file "npc_template.js", "public/javascripts/game/#{file_name}/#{file_name}_npc.js"
49
+ copy_file "settings_template.js", "public/javascripts/game/#{file_name}/#{file_name}_settings.js"
50
+ end
51
+
52
+ def add_image_files
53
+ copy_file "font.png", "public/images/game/font.png"
54
+ copy_file "cels.png", "public/images/game/cels.png"
55
+ end
56
+
57
+ def add_akihabara_image_files
58
+ copy_file "8x8s.png", "public/images/game/akihabara/8x8s.png"
59
+ copy_file "buttons.png", "public/images/game/akihabara/buttons.png"
60
+ copy_file "debugfont.png", "public/images/game/akihabara/debugfont.png"
61
+ copy_file "dpad.png", "public/images/game/akihabara/dpad.png"
62
+ copy_file "dpad320.png", "public/images/game/akihabara/dpad320.png"
63
+ copy_file "fontbig.png", "public/images/game/akihabara/fontbig.png"
64
+ copy_file "padbg.png", "public/images/game/akihabara/padbg.png"
65
+ end
66
+ def add_route_for_map
67
+ route ("match '#{file_name}' => 'game##{file_name}', :as => '#{file_name}'")
68
+ end
69
+
70
+ def add_jquery
71
+ copy_file "jquery.js", "public/javascripts/jquery.js"
72
+ end
73
+
74
+ def exit_message
75
+ puts "
76
+
77
+ Great success! The files you want to mess with most are probably:
78
+ public/javascripts/game/#{file_name}/#{file_name}_map.js
79
+ public/javascripts/game/#{file_name}/#{file_name}_settings.js
80
+ public/javascripts/game/#{file_name}/#{file_name}_npc.js
81
+ public/javascripts/game/resources.js
82
+
83
+ ==================================WARNING==================================
84
+
85
+
86
+ This will not work if you are using prototype
87
+ A line such as '<%= javascript_include_tag :defaults %>' in application.html.erb will yield unexpected, weird behavior
88
+ (mostly just breaking the page as far as I know so far).
89
+
90
+ A Jquery file has been added. You will need to include this somewhere in your application layout or view like so:
91
+ <%= javascript_include_tag 'jquery' %>
92
+ To fully convert to jquery from prototype, you may need to swap out your rails.js with something such as the file found at https://github.com/rails/jquery-ujs/tree/master/src
93
+
94
+ ===========================Warning over... sorry 'fai scurred you=======
95
+
96
+ Anyways, I'll be at github.com/evanburchard if you have any questions, bug reports, or feature requests.
97
+
98
+ Have fun,
99
+ -Evan
100
+ "
101
+ end
102
+
103
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,3 @@
1
+ BODY {
2
+ -webkit-user-select:none; margin:0px
3
+ }
@@ -0,0 +1,165 @@
1
+ var tilemaps;
2
+ var maingame;
3
+ var dialogues;
4
+ var faces;
5
+
6
+ function leave_page(website) {
7
+ $('canvas').fadeOut('slow', function() {
8
+ window.location = website;
9
+ maingame.gameIsHold = true;
10
+ });
11
+ }
12
+
13
+ function go() {
14
+
15
+ gbox.setGroups(["background","player","bonus","foes","walls","playerbullets","foesbullets","sparks","foreground","gamecycle"]);
16
+ // player, walls, bullets and foes are under z-index layer
17
+ gbox.setRenderOrder(["background",gbox.ZINDEX_LAYER,"sparks","foreground","gamecycle"]);
18
+
19
+ maingame=gamecycle.createMaingame("gamecycle","gamecycle");
20
+
21
+ // No level intro animation
22
+ maingame.gameIntroAnimation=function() { return true; }
23
+
24
+ // Change level
25
+ maingame.changeLevel=function(level) {
26
+ // Cleanup the level
27
+ gbox.trashGroup("playerbullets");
28
+ gbox.trashGroup("foesbullets");
29
+ gbox.trashGroup("foes");
30
+ gbox.trashGroup("bonus");
31
+ gbox.trashGroup("walls");
32
+ gbox.purgeGarbage(); // Since we're starting, we can purge all now
33
+ level={level:"yard"};
34
+ tilemaps.current=level.level;
35
+ gbox.createCanvas("tileslayer",{w:tilemaps[tilemaps.current].w,h:tilemaps[tilemaps.current].h});
36
+ gbox.blitTilemap(gbox.getCanvasContext("tileslayer"),tilemaps[tilemaps.current]);
37
+ toys.topview.spawn(gbox.getObject("player","player"),{x:player_starts_at["x"],y:player_starts_at["y"]});
38
+ tilemaps[tilemaps.current].addObjects();
39
+ }
40
+
41
+ maingame.initializeGame= init_game;
42
+
43
+ // Changes a tile in the map. It also adds smoke if asked.
44
+ maingame.setTileInMap=function(x,y,tile) {
45
+ help.setTileInMap(gbox.getCanvasContext("tileslayer"),tilemaps[tilemaps.current],x,y,tile);
46
+ }
47
+
48
+
49
+ // Starts a dialogue
50
+ maingame.startDialogue=function(id,pause) {
51
+ gbox.addObject({
52
+ group:"foreground",
53
+ id:"dialogue",
54
+ dialogueToRead:id,
55
+ pause:1+(pause==null?0:1), // Pauses a dialog for a while. Is important to wait a frame very time to cancel the last "b" key press (for interacting, for example)
56
+ initialize:function() {
57
+ gbox.getObject("player","player").doPause(true); // First pause the player
58
+ },
59
+ blit:function() {
60
+ if (this.pause)
61
+ this.pause--;
62
+ else if (toys.dialogue.render(this,"dialogue",dialogues[this.dialogueToRead])) { // If the dialogue is ended
63
+ gbox.getObject("player","player").doPause(false); // Unpause the player
64
+ gbox.trashObject(this); // Trash the dialogue itself.
65
+ }
66
+ }
67
+ });
68
+ }
69
+
70
+ // Add a still object. Are sprites that supports the z-index (houses, trees.) You can walk around these objects
71
+ maingame.addBlock=function(x,y,tileset,frame) {
72
+ gbox.addObject({
73
+ group:"walls",
74
+ tileset:tileset,
75
+ zindex:0, // Needed for zindexed objects
76
+ x:x,
77
+ y:y,
78
+ frame:frame,
79
+
80
+ initialize:function() {
81
+ toys.topview.initialize(this); // Any particular initialization. Just the auto z-index
82
+ },
83
+ blit:function() {
84
+ if (gbox.objectIsVisible(this)) {
85
+ // Then the object. Notes that the y is y-z to have the "over the floor" effect.
86
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.tileset,tile:this.frame,dx:this.x,dy:this.y+this.z,camera:this.camera,fliph:this.fliph,flipv:this.flipv});
87
+ }
88
+ }
89
+
90
+ });
91
+ }
92
+
93
+ // Add a npc (Not Playing Charachter)
94
+ maingame.addNpc=function(x,y,still,dialogue,questid,talking,has_shadow) {
95
+ // An easy way to create an NPC.
96
+ if (has_shadow==true){
97
+ var where_shadow = 0;
98
+ }
99
+ else {
100
+ var where_shadow = 1;
101
+ };
102
+ gbox.addObject({
103
+ questid:questid,
104
+ group:"walls",
105
+ tileset:"npc",
106
+ zindex:0, // Needed for zindexed objects
107
+ x:x,
108
+ y:y,
109
+ myDialogue:dialogue,
110
+ iamTalking:false,
111
+ shadow:{tileset:"shadows",tile:where_shadow},
112
+ frames:{
113
+ still:{ speed:6, frames:still },
114
+ talking:{ speed:6, frames:(talking==null?still:talking) }
115
+ },
116
+
117
+ doPlayerAction:function(sw) {
118
+ this.iamTalking=true; // go in talking mode
119
+ maingame.startDialogue(this.myDialogue); // Starts its dialogue. Is another object because of z-index
120
+ },
121
+
122
+ initialize:function() {
123
+ toys.topview.initialize(this); // Any particular initialization. Just the auto z-index
124
+ },
125
+
126
+ first:function(by) {
127
+ this.counter=(this.counter+1)%12;
128
+
129
+ if (this.iamTalking) {
130
+ this.frame=help.decideFrame(this.counter,this.frames.talking);
131
+ if (!gbox.getObject("foreground","dialogue")) {// Check if the dialogue ended
132
+ this.iamTalking=false; // Stop talking
133
+ if ((this.questid!=null)&&(!tilemaps.queststatus[this.questid])) {
134
+ tilemaps.queststatus[this.questid]=true; // If related to a quest, the quest is marked as done
135
+ maingame.addQuestClear();
136
+ }
137
+ }
138
+ } else
139
+ this.frame=help.decideFrame(this.counter,this.frames.still);
140
+ },
141
+
142
+ blit:function() {
143
+ if (gbox.objectIsVisible(this)) {
144
+ // Shadowed object. First draws the shadow...
145
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.shadow.tileset,tile:this.shadow.tile,dx:this.x,dy:this.y+this.h-gbox.getTiles(this.shadow.tileset).tileh+4,camera:this.camera});
146
+ // Then the object. Notes that the y is y-z to have the "over the floor" effect.
147
+ gbox.blitTile(gbox.getBufferContext(),{tileset:this.tileset,tile:this.frame,dx:this.x,dy:this.y+this.z,camera:this.camera,fliph:this.fliph,flipv:this.flipv});
148
+ }
149
+ }
150
+
151
+ });
152
+ }
153
+ gbox.go();
154
+ }
155
+
156
+ window.addEventListener('load', function () {
157
+ help.akihabaraInit(page_title);
158
+ gbox.setCallback(go);
159
+
160
+ loadResources();
161
+
162
+ gbox.loadAll();
163
+ }, false);
164
+
165
+
@@ -0,0 +1,2 @@
1
+ class GameController < ApplicationController
2
+ end
@@ -0,0 +1,124 @@
1
+ // ---
2
+ // Copyright (c) 2010 Francesco Cottone, http://www.kesiev.com/
3
+ // ---
4
+
5
+ var gamecycle={
6
+ createMaingame:function(id,group) {
7
+ return gbox.addObject({
8
+ id:id,
9
+ group:group,
10
+ counter:0,
11
+ difficulty:0,
12
+
13
+ step:100,
14
+ isready:false,
15
+
16
+ hud:{},
17
+
18
+
19
+ // Level intro animation
20
+
21
+ gameIntroAnimation:function(reset) {
22
+ },
23
+
24
+ // game title animation
25
+ gameTitleIntroAnimation:function(reset) {
26
+ },
27
+
28
+
29
+ // CHECK
30
+
31
+ gameIsHold:function() { // Use this clause to check collision and kill player: if true the level is changing
32
+ return (this.step==400)||(this.step==401);
33
+ },
34
+
35
+ // PRIVATES
36
+
37
+ setStep:function(st) {
38
+ this.step=st;
39
+ this.isready=false;
40
+ },
41
+
42
+ _resetGroups:function() {
43
+ var g=gbox.getGroups();
44
+ for (var i=0;i<g.length;i++)
45
+ if (g[i]!=this.group) gbox.clearGroup(g[i]);
46
+ gbox.soloGroup(this.group);
47
+ },
48
+
49
+ stepIsReady:function() { this.isready=true; },
50
+ blit:function() {
51
+ var ok=false;
52
+ switch (this.step) {
53
+ case 100:
54
+ case 102: { // Press Start / Menu
55
+ if (!this.isready&&(this.step==100)) {
56
+ this._resetGroups();
57
+ this.gameTitleIntroAnimation(true);
58
+ }
59
+ this.gameTitleIntroAnimation(false);
60
+ switch (this.step) {
61
+ case 100: { // Press to start
62
+ if (!this.isready) {
63
+ this.stepIsReady();
64
+ }
65
+ this.setStep(102);
66
+ break;
67
+ }
68
+ case 102: { // Fader
69
+ if (!this.isready) {
70
+ this._resetGroups();
71
+ toys.resetToy(this,"fadeout");
72
+ this.stepIsReady();
73
+ }
74
+ this.setStep(200);
75
+ break;
76
+ }
77
+ break;
78
+ }
79
+ break;
80
+ }
81
+ case 200:// Game intro animation
82
+
83
+ case 300:// Start game
84
+
85
+
86
+
87
+ { // Game playing
88
+ if (!this.isready) {
89
+ switch (this.step) {
90
+ case 200: { // Game intro
91
+ toys.resetToy(this,"fadein");
92
+ this.level=null;
93
+ this._nextlevel=null;
94
+ this.hud=toys.ui.hud("maingamehud");
95
+
96
+ this.initializeGame();
97
+ this.gameIntroAnimation(true);
98
+
99
+ break;
100
+ }
101
+ case 300: {
102
+ // Game start
103
+ gbox.playAllGroups();
104
+ this.changeLevel(this._nextlevel);
105
+ }
106
+ }
107
+ this.stepIsReady();
108
+ }
109
+
110
+ switch (this.step) {
111
+ case 200: { // Game intro
112
+ if (this.gameIntroAnimation(false)) this.setStep(300);
113
+ break;
114
+ }
115
+ }
116
+
117
+ this.hud.blit();
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ });
123
+ }
124
+ }