Hi All,
Here I'm sharing the library we've been working for a while in Pixelatom.
This library allows you to load .tmx files created with Tiled (http://www.mapeditor.org/), which is an amazing open-source multi-platfom tile map editor, and render them as BennuGD scrolls.
Features
* Object Placement support
* Multiple layers
* Support unlimited sized maps
* Tileset loading
* Scroll rendering already done
* Excellent performance
The library stills in development and there are some considerations:
* We can render up to 10 layers (Bennu only have 10 scrolls)
* By now, we can load up to 256 object layers with 256 objects each as much (it'll be fixed in the future)
* Custom properties are not supported yet.
We haven't found any bug yet, but I'm pretty sure there could be some, mostly because we play a lot with dynamic memory allocation, so, please, if you find something let us know.
About the package
The game coming as example was made during a GameJam in 48 hours, so don't pay attention to the mess, but it shows pretty well how to use the library. You'll find there how to use the scroll with your processes and how to use a hardness layer to place your character. The game is not open source, it's licensed under creative common, to see what you can do with it read here: http://creativecommons.org/licenses/by-nc-nd/3.0/
The library itself is placed under the "libraries" folder, and it's licenced under MIT license. So you can do pretty much whatever you want to with that code.
Download the library with the game here:
http://dl.dropbox.com/u/73385/cardiac%20runner%20source%20code.tar.bz2
do you want a handheld port ?
It's open source but some rights reserved, am I right?
BennuGD .Net Tools also support this format when you edit maps
Quote from: FreeYourMind on January 30, 2013, 02:53:34 PM
do you want a handheld port ?
I'll once I made some edits, I'll let you know, thanks for the offering.
Quote from: PiXeL on January 30, 2013, 02:55:11 PM
It's open source but some rights reserved, am I right?
the library is "open source", you can use it as you want.
the game is copyrighted, I'm only allowing you to see the source, and distribute it as I gave it to you. You can't use it for anything else.
Quote from: FreeYourMind on January 30, 2013, 02:56:24 PM
BennuGD .Net Tools also support this format when you edit maps
cool :)
APORTE GRANDE
SERA INCLUIDO EN EL BENNUPACK
This is IMPRESSIVE, thanks a lot for sharing!
Pretty nice! Good use of regex, I can learn something from that. ;)
Will this be ported to the dreamcast?
Quote from: DoctorN on February 01, 2013, 09:56:21 PM
Will this be ported to the dreamcast?
That would be very interesting, but I've never worked with the dreamcast port. I hope somebody else with experience could take that chance
I copied the entire libraries folder into the directory of my game. Then I added
include "libraries/tiledmap/tiledmap.lib";
to it. However I am getting the error:
(http://forum.bennugd.org/index.php?action=dlattach;topic=3437.0;attach=2854)
javis... the lib must include the imports that it need.
is that the issue? because I can compile and run his game but when I copied the libraries folder into my game and included that file. It says I was missing that, so I ctl+f'd every file in the directory of his game and found that variable in that one file. So I have been confused ever since.
Quote from: SplinterGU on February 02, 2013, 06:07:11 PM
javis... the lib must include the imports that it need.
Right, I missed that one, please include the mod required by that function. (mod_screen)
I'll fix it in future versions.
thanks!
okay I got half of it working right now. pay no attention to the player.prg, its just movement stuff.
//Velocity And Movement Tester
//By: Nicholas Wolf
//Date: 1/29/2013
program velocity_test;
import "mod_grproc";
import "mod_wm"
import "mod_key"
import "mod_proc"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_draw"
import "mod_debug"
import "mod_say";
import "mod_screen";
import "mod_math";
import "mod_time";
import "mod_dir";
import "mod_joy";
import "mod_sound";
include "libraries/tiledmap/tiledmap.lib";
global
//the name we will give our level
_tiled_map map; // the map we'll load
_tiledmap_viewport viewport; //a scroller window
//the dimmensions of objects
player_dim_x = 32;
player_dim_y = 32;
//the object of the player
character_process player_s;
private
//The resolution of the game
game_width = 320;
game_height = 240;
game_color_depth = 16;
//The resolution of the screen
screen_width = 640;
screen_height = 480;
begin
//get the size of the monitor you are using
get_desktop_size(&screen_width, &screen_height);
say("Monitor is: " + screen_width + "x" + screen_height);
//set the games resolution
set_mode(game_width,game_height,game_color_depth);
set_fps(60,0);
render_level();
//spawn the player
//player(320/2,240-(player_dim_y/2));
loop
//the scroller
viewport.x = player_s.x - (game_width/2);
viewport.y = player_s.y-160;
//press esc or click X to exit game
if(key(_esc) or exit_status)
exit("goodbye",0);
end
frame;end
tiledmap_stop(viewport);
tilemap_unload_map(map);
end
include "player.prg"
process render_level();
public
int i,j;
begin
//load the tiled map file
tilemap_load_map(map,"test.tmx");
tilemap_start(viewport, map, 320, 240);
//spawn the objects in the tiled map file
for (i=0; i< map.objectgroup_count ; i++)
for (j=0; j< map.objectgroups[i].objectcount ; j++)
switch(map.objectgroups[i].objects[j].typename)
case "player":
player(map.objectgroups[i].objects[j].x,map.objectgroups[i].objects[j].y);
end
end
end
end
end
the problem is with this line of code
tilemap_start(viewport, map, 320, 240);
if I leave it there, the game crashes. if I //comment is, the game runs, but there are no tiles. now, I will upload my source. im not reuploading the library since I havent modified it at all.
I found the problem
Right now, and maybe forever, I can only load tmx files saved with the Store tile layer data option set to CSV. (you can change that in the preferences dialog) You have it selected to Base64.
I've also modified your code to assign the player process to the player_s variable.
Ok. I know we are grateful that you released the code you made to run .tmx files but its still haveily set up to work with your game. I have no idea what to touch. The only thing I got working was getting processes to be placed.
Quote from: DoctorN on February 04, 2013, 01:40:25 AM
Ok. I know we are grateful that you released the code you made to run .tmx files but its still haveily set up to work with your game. I have no idea what to touch. The only thing I got working was getting processes to be placed.
Just ask any question I'll help you as far as I can.
did you get it to work?
Quote from: DoctorN on February 04, 2013, 02:05:26 AM
did you get it to work?
yap, I've replied you already. I've edited the message before you reply.
thanks! now I have got my game working now. I couldnt figure out a good way to auto-fall (when there is nothing bellow you) and you are standing (havent incorporated walking yet). check line 171 of player.prg
When I get home after work I'll take a look at your code. In the mean time, I suggest you to take a look at the character process included with the game, it uses a hardness map (a hidden tiled map layer) and a function to check the color of the pixel below the player, to check if it's over the floor or not.
I got some stuff down, but i want to make it simplier so you can have it with your library
Quote from: DoctorN on February 05, 2013, 10:15:16 PM
I got some stuff down, but i want to make it simplier so you can have it with your library
Would be great to include a simplier example with the library, but I wouldn't include that AS PART of the library, since it's game logic and depends much on what you want your character to behave like. Just lets say you want to use the engine to make a strategic game like C&C and not a platformer, then the library wouldn't be useful.
process player(x,y);
private
//location
int y_prev = 0; //for collision
//key presses
bool key_right = false;
bool key_left = false;
bool key_jump = false;
//status
string status = "falling";
//movements
int v = 0; //velocity
int v_min = -4; //the minimum a velocity can get
int v_max = 4; //the maximum a velocity can get
int v_timer = 0; //a counter that will steadily increase/decrease v
int v_timer_max = 5; //the max time a v_timer will set itself to
int dir = 0;
int h_speed = 1.5;
int y_formula;
bool can_jump = true;
bool landing = false;
bool moving = false;
//collision
int i = 0;
int j = 0;
int collision_bottom_l = 0;
int collision_bottom_r = 0;
int collision_top_l = 0;
int collision_top_r = 0;
int collision_left = 0;
int collision_right = 0;
int collision = 0;
begin
graph = load_png("player.png");
ctype = c_scroll;
loop
write(0,0,0,0,"STATS:");
write(0,0,8,0,"dir: "); write_var(0,56,8,0,dir);
write(0,0,16,0,"v: "); write_var(0,56,16,0,v);
write(0,0,24,0,"v_timer: "); write_var(0,56,24,0,v_timer);
write(0,0,32,0,"status: "); write_string(0,56,32,0,&status);
//formula for moving
x+=dir*h_speed;
y_formula=pow(v,1);
y_prev = y;
y+=y_formula;
if(key(_right) and !key(_left))
key_right=true;
else
key_right=false;
end
if(key(_left) and !key(_right))
key_left=true;
else
key_left=false;
end
if(key(_control))
key_jump = true;
else
key_jump = false;
end
//moving
if(key_right)
for(i = -8; i <= 8; i++)
collision=tilemap_get_pixel(map,0,x+16,y+i);
if(collision != RGB(255,0,0))
dir = 1;
else
dir = 0;
end
end
end
if(key_left)
for(i = -8; i <= 8; i++)
collision=tilemap_get_pixel(map,0,x-16,y+i);
if(collision != RGB(255,0,0))
dir = -1;
else
dir = 0;
end
end
end
if((!key_right and !key_left) or (key_right and key_left))
dir = 0;
end
//jump key
if(key_jump)
if(can_jump)
status = "jumping";
can_jump = false;
end
else
if(status == "jumping")
status = "falling";
end
if(status == "");
can_jump = true;
end
end
//jumping
if(status == "jumping")
if(v>v_min) //since you are //jumping, you want v to reach v_max
if(v_timer>0)
v_timer--;
else
v--;
v_timer = v_timer_max;
end
else //if v is the minimum it can get, begin falling
v_timer = 0;
status = "falling";
end
for(i = 0; i <= 16; i++) //hitting the cieling
collision=tilemap_get_pixel(map,0,x,y-i);
if(collision == RGB(255,0,0))
if(v<0)
v = 0;
end
v_timer = 0;
status = "falling";
end
end
end
//falling
if(status == "falling")
if(v<v_max) //since you are falling, you want v to reach v_min, which is -v_max
if(v_timer>0)
v_timer--;
else
v++;
v_timer = v_timer_max;
end
end
for(i = 0; i <= 16; i++) //hitting the ceiling
collision=tilemap_get_pixel(map,0,x,y-i);
if(collision == RGB(255,0,0))
if(v<0)
v = 0;
end
v_timer = 0;
status = "falling";
end
end
for(i = 0; i <= 16; i++) //landing on the floor
collision=tilemap_get_pixel(map,0,x,y+i);
if(collision == RGB(255,0,0))
v = 0;
v_timer = 0;
status = "";
y-=v;
end
end
end
frame;end
end[code]
Okay, I have repotimized my code, it works a little better, but I need your help because you made the tile engine, so I need your expertise in it. Once I got it down, im good.
PROBLEMS:
1. you can fall if there is no free space, I didnt put it in this code because the status will always be "falling". I will need help on this
2. If you add this to ceiling code:
[code]collision=tilemap_get_pixel(map,0,x-16,y-i);
if(collision == RGB(255,0,0))
if(v<0)
v = 0;
end
v_timer = 0;
status = "falling";
end
collision=tilemap_get_pixel(map,0,x+16,y-i);
if(collision == RGB(255,0,0))
if(v<0)
v = 0;
end
v_timer = 0;
status = "falling";
end
and this to the fall code
collision=tilemap_get_pixel(map,0,x+16,y+i);
if(collision == RGB(255,0,0))
v = 0;
v_timer = 0;
status = "";
y-=v;
end
collision=tilemap_get_pixel(map,0,x-16,y+i);
if(collision == RGB(255,0,0))
v = 0;
v_timer = 0;
status = "";
y-=v;
end
you will instead stick to the wall, doesnt matter if there is ground below you. but these are needed so that you can the corners (otherwise you will go through half the block).
So those are the problems that I can't fix and have wasted a long time trying to fix. I would like to see a reply soon :). thanks
updated post
Hi, I'm out of the city for the weekend. Let me check this as soon as I get back home. It should't be hard to fix.
Thanks
have you had the chance to look at it? thanks
Quote from: DoctorN on February 18, 2013, 03:32:57 PM
have you had the chance to look at it? thanks
I came back today and I'm at work roght now, I'll take a look asap and let you know.
okay thanks
Ok
I couldn't fix it, basically for two main reasons:
* You are checking the collision with the floor only after a JUMP, but you have to realize you're always falling, that's how gravity works. So what you must do is to check the bottom collision in all frames and add a vertical (y) speed until you collide with the floor.
* In all the frames you have to make a fix left and right collision too, if you collide with the left, you have to move your character to the right until you are no longer colliding with the wall. Same thing with the wall at the right.
So basically if you want me to fix your code I would be rewritting most of the logic of the player.
I'll be posting a basic example of how hardness map should be implemented in a character process soon.
I was really hoping I could have something working soon. I need to get done what I need to get done very soon. This is the only other thing I could think of:
//ground detection
for(i = 0; i <= 16; i++)
collision=tilemap_get_pixel(map,0,x,y+i);
if(collision != RGB(255,0,0))
if(status != "jumping")
status = "falling";
end
can_jump = false;
else
status = "";
v = 0;
can_jump = true;
end
end
//falling
if(status == "falling")
if(v_timer > 0)
v_timer--;
else
if(v < v_max)
v++;
end
v_timer = v_timer_max;
end
end
//jumping
if(key_jump)
if(can_jump == true)
status = "jumping";
end
end
if(status == "jumping")
if(apex < apex_reached)
if(apex_timer > 0)
apex_timer--;
else
apex++;
apex_timer = apex_timer_max;
end
else
status = "falling";
end
if(v_timer > 0)
v_timer--;
else
if(v > v_min)
v--;
end
v_timer = v_timer_max; //5
end
else
apex = 0;
apex_timer = apex_timer_max; //5
end[code]
the problem with this:
*no ceiling (yet)
*jumping is very weird (you jump higher)
*you can fall through the edge blocks
*sometimes you land 1/2 pixels into a block and that screws everything up
*when you are on the platforms that are 2x1, you will sink
please man, ive been twidling my thumbs and trying to make code. nothing works. can you help me?
ok, I think you need to rewrite your character process. Take a look at the example we've provided and try to understand it.
the keys of the logic are the following :
have 2 vars for the movement. inc_c and inc_y are the value on pixels the player will move on every frame.
on your loop:
<code>
inc_y += gravity; // ALWAYS falling
if(inc_y > max_vertical_speed)
inc_y = max_vertical_speed;
end
</code>
I'm sorry but the code to your cardiac is too proprietary for what I need to do. I really need to get this done, you realize how much time I have spent not getting anything done because I am trying to get the players physics to work? I won't rest until it's done and it's killing me, it's keeping me up at night trying to figure out how come it isn't working. I see that the tiles are rendered the same way as in my platform example, but you don't have the same style of collision
tile[(x-player.dimx/2)/block_size][(y-player.dimy/3)/block_size]
and I don't know where to put it in the code or how to make it work since it isn't looking for kind it's looking for rgb. I have realized that the english section of this forum is dead but this is the only active place for bennu help. I am so lost at this point that this is all I can comprehend at the moment.
process player(x,y);
private
//location
int y_prev = 0; //for collision
//key presses
bool key_right = false;
bool key_left = false;
bool key_jump = false;
//status
string status = "falling";
//movements
int v = 0; //velocity
int v_min = -4; //the minimum a velocity can get
int v_max = 4; //the maximum a velocity can get
int v_timer = 5; //a counter that will steadily increase/decrease v
int v_timer_max = 5; //the max time a v_timer will set itself to
int fall;
int dir = 0;
int h_speed = 1.5;
int y_formula;
bool falling = false;
bool jumping = false;
bool on_ground = false;
bool moving = false;
//collision
int i = 0;
int j = 0;
int collision = 0;
begin
graph = load_png("player.png");
ctype = c_scroll;
loop
write(0,0,0,0,"STATS:");
write(0,0,8,0,"dir: "); write_var(0,56,8,0,dir);
write(0,0,16,0,"v: "); write_var(0,56,16,0,v);
write(0,0,24,0,"v_timer: "); write_var(0,56,24,0,v_timer);
write(0,0,32,0,"status: "); write_string(0,56,32,0,&status);
//formula for moving
x += dir*h_speed;
//y_formula = (fall-v);
y_prev = y;
//y = y + y_formula;
y = y + v;
if(key(_right) and !key(_left))
key_right=true;
else
key_right=false;
end
if(key(_left) and !key(_right))
key_left=true;
else
key_left=false;
end
if(key(_control))
key_jump = true;
else
key_jump = false;
end
//moving
if(key_right)
collision=tilemap_get_pixel(map,0,x+16,y);
if(collision != RGB(255,0,0))
dir = 1;
else
dir = 0;
end
collision=tilemap_get_pixel(map,0,x+16,y+16);
if(collision != RGB(255,0,0))
dir = 1;
else
dir = 0;
end
collision=tilemap_get_pixel(map,0,x+16,y-16);
if(collision != RGB(255,0,0))
dir = 1;
else
dir = 0;
end
end
if(key_left)
collision=tilemap_get_pixel(map,0,x-15,y);
if(collision != RGB(255,0,0))
dir = -1;
else
dir = 0;
end
collision=tilemap_get_pixel(map,0,x-15,y+16);
if(collision != RGB(255,0,0))
dir = -1;
else
dir = 0;
end
collision=tilemap_get_pixel(map,0,x-15,y-16);
if(collision != RGB(255,0,0))
dir = -1;
else
dir = 0;
end
end
if((!key_right and !key_left) or (key_right and key_left))
dir = 0;
end
//air movement
if(!jumping)
collision=tilemap_get_pixel(map,0,x,y+16);
if(collision != RGB(255,0,0))
falling = true;
on_ground = false;
else
v = 0;
v_timer = v_timer_max;
on_ground = true;
falling = false;
end
collision=tilemap_get_pixel(map,0,x+16,y+16);
if(collision != RGB(255,0,0))
falling = true;
on_ground = false;
else
v = 0;
v_timer = v_timer_max;
on_ground = true;
falling = false;
end
collision=tilemap_get_pixel(map,0,x-15,y+16);
if(collision != RGB(255,0,0))
falling = true;
on_ground = false;
else
v = 0;
v_timer = v_timer_max;
on_ground = true;
falling = false;
end
end
if(falling)
if(v < 0)
v = 0;
end
if(v < v_max)
if(v_timer > 0)
v_timer--;
else
v++;
v_timer = v_timer_max;
end
end
end
if(jumping)
if(v > v_min)
if(v_timer > 0)
v_timer--;
else
v--;
v_timer = v_timer_max;
end
else
falling = true;
jumping = false;
end
end
say(falling);
if(key_jump)
if(!falling and !jumping and on_ground)
jumping = true;
on_ground = false;
end
end
frame;end
end
And this current revision (revision 207) is incomplete. Will I still work on it after I post this, yes? Because I can't twiddle my thumbs any longer. You should already have my velocity.prg, nothing in that has changed. Please, help me out. I just want things to be checked on a +16 and -16 scale. Can you please sit down and help a guy out? Thanks
Hey sorry for the late reply, I'm really busy this week.
Let me take a look at what you've done.
Maybe this saturday I can come up with an simpler character example.
okay thanks, will you take into mind what i said about the 16 pixel thing?
Yes, I'll make it configurable :)
just checking to see how you are at with progress
Is This similar to mod_mappy?
I believe it's different.
¿Don't?
http://tilemap.co.uk/mappy.php
i read the files inside the library (they could be renamed .prg's and still work) they read the .txt file that tiled makes.
I'm sorry guys that I couldn't advance with the example. Last friday a thief broke into my house and tied up my girlfriend.
I've been busy the whole weekend trying to be with her the most I could.
I'll try to do an example tody for you
I am sorry to hear that :(
Well I hope you can get it done soon :)
That's a horrible story. :o Is she allright? It sounds pretty shocking. Just the thought that someone sneaks into your house and hurts your loved one is pretty devistating.
Quote from: handsource-dyko on March 04, 2013, 03:33:18 PM
That's a horrible story. :o Is she allright? It sounds pretty shocking. Just the thought that someone sneaks into your house and hurts your loved one is pretty devistating.
yeah it was horrible. fortunately he didin't youch her and she is fine. obviously it was shoking for her and she is still afraid, now she want us to move to another place :P
hey its been a week hows the tutorial?
Hey sorry during the week I can't advance anything, I'm working on it now. thanks for waiting
thanks! you think youll have it up soon?
Finaly, here it's!
First thing you need to know, this is not a basic example of how to use the library, and this is not an example made from your code.
This is, what I believe, what you are having problems with, and need to understand before coding a character or a player on our library.
This is an hardness map example. This contains the basic logic of a player character movement over a hardness map. Once you understand this you should be able to start coding your character using our tiled library.
I can't think on a better, or a simpler example than this one. So please, put all the time you need to study and understand the logic. I think it'll be very useful for your future projects.
thanks! ill study it for a few days
I just straight ported the code into my player.prg and i just fall through the floor, i analyze it and i try to fix things cause the movement is so similar to what you have in cardiac, but nothing is colliding. So I reverted it back to a straight port for you to look at. main.prg should be the same so just replace the player.rpg with this one. I did change char_height to player_dim_y and char_width to player_dim_x. Thanks
process player(x,y);
public
string status = "standing";
private
//location
int inc_x = 0; // horizontal speed
int inc_y = 0; // vertical speed
int y_prev = 0; //for collision
//key presses
bool key_right = false;
bool key_left = false;
bool key_jump = false;
bool pressed_jump = false;
//movement
byte gravity = 1;
byte jump_height = -12;
byte max_vertical_speed = 2;
byte char_speed = 0;
byte char_max_speed = 2;
//status
int dir = 0;
//collision
int collision_bottom = 0; // down collision
int collision_top = 0; // up collision
int collision_left = 0; // left collision
int collision_right = 0; // right collision
int i = 0;
int j = 0;
begin
graph = load_png("player.png");
ctype = c_scroll;
loop
write(0,0,0,0,"STATS:");
write(0,0,8,0,"dir: "); write_var(0,56,8,0,dir);
write(0,0,32,0,"status: "); write_string(0,56,32,0,&status);
// Gravity
inc_y += gravity;
if(inc_y > max_vertical_speed)
// Change the max_vertical_speed value if you want to jump higher
inc_y = max_vertical_speed;
end
y_prev = y;
y += inc_y;
x += inc_x;
// Collision checking for all directions
// BOTTOM
for(i = 0; i <= player_dim_y; i++)
for(j = -(player_dim_y/2); j <= (player_dim_y/2); j++)
collision_bottom=map_get_pixel(map,map,x+j,y+i);
if(collision_bottom == RGB(255,0,0) or (collision_bottom == RGB(0,255,0) and (y+i-player_dim_y>y_prev) and inc_y >= 0))
// Went through the floor, let's fix the position
y--;
inc_y = 0;
if(status == "jumping")
// Fix for slopes, change the 3 to something higher if you have problems jumping on slopes
status = "standing";
end
end
end
end
// TOP
for(i = 0; i <= player_dim_y; i++)
for(j = -(player_dim_y/2); j <= (player_dim_y/2); j++)
collision_top=map_get_pixel(map,map,x+j,y-i);
if(collision_top == RGB(255,0,0))
y++;
if(inc_y < 0)
inc_y *= -1;
end
end
end
end
// LEFT
for(i = 0; i <= player_dim_x; i++)
for(j = -(player_dim_x/2); j <= (player_dim_x/2); j++)
collision_left=map_get_pixel(map,map,x-i,y+j);
if(collision_left == RGB(255,0,0))
x++;
if(inc_x < 0)
inc_x = 0;
end
end
end
end
// RIGHT
for(i = 0; i <= player_dim_x; i++)
for(j = -(player_dim_x/2); j <= (player_dim_x/2); j++)
collision_right=map_get_pixel(map,map,x+i,y+j);
if(collision_right == RGB(255,0,0))
x--;
if(inc_x > 0)
inc_x = 0;
end
end
end
end
// End collision checking
if(!key(_K) and (status == "standing" or status == "running") and inc_y == 0)
// Lets the player jump if it's standing
pressed_jump = 0;
inc_y++;
elseif(key(_K) and inc_y > 5)
// Avoids jumping until the jump button is released after a jump
pressed_jump = 1;
elseif(!key(_K) and (status == "standing" or status == "running") and inc_y > 3)
// Jumping status if you're falling
status = "jumping";
end
if(!key(_K) and status == "jumping")
// Going down, the player released the jump button
inc_y++;
end
// Status engine
switch(status):
case "running":
if(key(_K) and status != "jumping" and pressed_jump == 0 and inc_y <= 0)
// The player can jump only if: it's not already jumping, the button has been released from the previous jump, and it's standing on the floor
status = "jumping";
pressed_jump = 1;
inc_y = jump_height;
elseif(!key(_D) and !key(_A))
// Not pressing any key, the player is standing
status = "standing";
else
// Player is running
char_speed = char_max_speed;
if(key(_D))
if(inc_x < char_speed)
inc_x++;
end
flags = 0;
elseif(key(_A))
flags = 1;
if(inc_x > (char_speed*(-1)))
inc_x--;
end
end
end
end
case "standing":
if(key(_K) and status != "jumping" and pressed_jump == 0 and inc_y <= 0)
// The player can jump only if: it's not already jumping, the button has been released from the previous jump, and it's standing on the floor
status = "jumping";
pressed_jump = 1;
inc_y = jump_height;
if(inc_x > 0)
inc_x--;
elseif(inc_x < 0)
inc_x++;
end
elseif(key(_D) or key(_A))
// Player is running
status = "running";
else
if(inc_x > 0)
// A little inertia if the player has been running
inc_x--;
elseif(inc_x < 0)
inc_x++;
end
end
end
case "jumping":
if(key(_D) or key(_A))
// Player is moving in the air
char_speed = char_max_speed;
if(key(_D))
if(inc_x < char_speed)
inc_x++;
end
flags = 0;
elseif(key(_A))
flags = 1;
if(inc_x > (char_speed*(-1)))
inc_x--;
end
end
end
if(collision_bottom == RGB(255,0,0) )
// Player hit the floor
inc_y = 0;
status = "standing";
end;
end
end
frame;end
end
UPDATE:
this is the code ive tweaked around with. only colliding into the walls will work now.
process player(x,y);
public
string status = "standing";
private
//location
int inc_x = 0; // horizontal speed
int inc_y = 0; // vertical speed
int y_prev = 0; //for collision
//key presses
bool key_right = false;
bool key_left = false;
bool key_jump = false;
bool pressed_jump = false;
//movement
int gravity = 1;
int jump_height = -11;
int max_vertical_speed = 12;
int char_speed = 0;
int char_max_speed = 2;
//status
int dir = 0;
//collision
int collision_bottom = 0; // down collision
int collision_top = 0; // up collision
int collision_left = 0; // left collision
int collision_right = 0; // right collision
int i = 0;
int j = 0;
begin
graph = load_png("player.png");
ctype = c_scroll;
loop
write(0,0,0,0,"STATS:");
write(0,0,8,0,"dir: "); write_var(0,56,8,0,dir);
write(0,0,32,0,"status: "); write_string(0,56,32,0,&status);
x+=inc_x;
y+=inc_y;
inc_y += gravity;
if(inc_y > max_vertical_speed)
// Change the max_vertical_speed value if you want to jump higher
inc_y = max_vertical_speed;
end
y_prev = y;
if(key(_right) and !key(_left))
key_right=true;
else
key_right=false;
end
if(key(_left) and !key(_right))
key_left=true;
else
key_left=false;
end
if(key(_control))
key_jump = true;
else
key_jump = false;
end
//moving
for(i = -(player_dim_y/2)-1; i <= (player_dim_y/2)+1; i += (player_dim_y/2))
//right
collision_right=tilemap_get_pixel(map,0,x+(player_dim_x/2),y+i);
if(collision_right != RGB(255,0,0))
if(key_right) collision_left=0; inc_x = 2; end
else
if(key_right) collision_left=0; inc_x = 0; end
end
//left
collision_left=tilemap_get_pixel(map,0,x-(player_dim_x/2)-2,y+i);
if(collision_left != RGB(255,0,0))
if(key_left) collision_right=0; inc_x = -2; end
else
if(key_left) collision_right=0; inc_x = 0; end
end
end
//if both keys are pressed (or none), inc_x will be 0 as well as the collisions
if((!key_right and !key_left) or (key_right and key_left))
inc_x = 0;
collision_right=0;
collision_left=0;
end
//jumping
//falling
for(i = -(player_dim_y/2); i <= 0; i++)
for(j = -(player_dim_x/2)-1; j <= (player_dim_x/2)+1; j += (player_dim_x/2))
collision_bottom=map_get_pixel(map,0,x+j,y+i);
if(collision_bottom == RGB(255,0,0))
y--;
inc_y = 0;
end
end
end
//ceiling
for(i = 0; i <= player_dim_y; i++)
for(j = -(player_dim_x/2)-1; j <= (player_dim_x/2)+1; j += (player_dim_x/2))
collision_top=map_get_pixel(map,0,x+j,y-i);
if(collision_top == RGB(255,0,0))
y++;
if(inc_y < 0)
inc_y *= -1;
end
end
end
end
frame;end
end
ill upload my level too. and heres main if you need it
//Velocity And Movement Tester
//By: Nicholas Wolf
//Date: 1/29/2013
program velocity_test;
import "mod_grproc";
import "mod_wm"
import "mod_key"
import "mod_proc"
import "mod_video"
import "mod_text"
import "mod_map"
import "mod_draw"
import "mod_debug"
import "mod_say";
import "mod_screen";
import "mod_math";
import "mod_time";
import "mod_dir";
import "mod_joy";
import "mod_sound";
include "libraries/tiledmap/tiledmap.lib";
global
//the name we will give our level
_tiled_map map; // the map we'll load
_tiledmap_viewport viewport; //a scroller window
//the dimmensions of objects
player_dim_x = 32;
player_dim_y = 32;
//the object of the player
character_process player_s;
private
//The resolution of the game
game_width = 320;
game_height = 240;
game_color_depth = 16;
//The resolution of the screen
screen_width = 960;
screen_height = 720;
begin
//get the size of the monitor you are using
//get_desktop_size(&screen_width, &screen_height);
//say("Monitor is: " + screen_width + "x" + screen_height);
//set the games resolution
scale_resolution = screen_width * 10000 + screen_height ;
scale_resolution_aspectratio = SRA_PRESERVE;
//full_screen = true;
set_mode(game_width,game_height,game_color_depth);
set_fps(60,0);
render_level();
loop
//the scroller
viewport.x = player_s.x - (game_width/2);
viewport.y = player_s.y-160;
//press esc or click X to exit game
if(key(_esc) or exit_status)
exit("goodbye",0);
end
write(0,0,230,0,"FPS: ");write_int(0,30,230,0,&fps);
frame;end
tiledmap_stop(viewport);
tilemap_unload_map(map);
end
include "player.prg"
process render_level();
public
int i,j;
begin
//load the tiled map file
tilemap_load_map(map,"test.tmx");
tilemap_start(viewport, map, 320, 240);
//spawn the objects in the tiled map file
for (i=0; i< map.objectgroup_count ; i++)
for (j=0; j< map.objectgroups[i].objectcount ; j++)
switch(map.objectgroups[i].objects[j].typename)
case "player":
player_s = player(map.objectgroups[i].objects[j].x+(player_dim_x/2),map.objectgroups[i].objects[j].y+(player_dim_y/2));
end
end
end
end
end
other than that it uses the libraries from cardiac. ALSO to note, if I put a background into tiled, it doesnt load up in the game.
you think you can take a look? when i say(collision_bottom), all that returns is -1.
EDIT:
changed it to tilemap_get_pixel and it returns values, so I will work on the code again tomorrow
Cool! I was about to suggest that. Sorry for the late reply, I always can work on it just on fridays
Thanks! I got some stuff working, im splitting up my engine into different segments so I can them join them up later. Right now I am working on enemy AI, and I noticed that if I kill the process, I get this error
(http://forum.bennugd.org/index.php?action=dlattach;topic=3437.0;attach=2952)
I was trying to make a way so if I pressed like key F5 in main, it would reload everything. I need your help in this because I need to know how to unload the tilemap and reload it. basically F5 would just bring up the render_level(); process and the process would check if the enemy process existed (and would then remove it) as well as check if tilemap!=0 (but i don't know how to unload it). thanks
hehe there is a function to stop the tiled map and unload everything. it's very important because it free the memmory allocated when creating maps. I don't recall the name of the function right now, but it's pretty clear in the example (cardiac runner) please take a look there.
thanks!
its tile_map_unload. your program has let_me_alone(); in the main and that didnt work for me, nor do i think it will work later on once my game gets more beefy. for some reason killing that process crashes the game. can you take a look? thanks
Right, I use let_me_alone() in the main process because before unloading the stage I need to kill all the processes in the game. You must use it in the same loop that will restart the stage again. I mean, you could kill your processes manually too, but the error you're getting is because you're trying to access to a process already dead. Try checking them with exists() before accessing a property.
can you show me some code on how to kill it?
and dont just say "put let_me_alone(); in the main process" I tried putting it before the loop and in the loop; it will only work for me if it is in the loop and there is nothing to signal it (so it is constantly doing let_me_alone();) and that's what I call a game-breaker. A new method will have to be created.
Quote from: DoctorN on March 27, 2013, 04:48:25 AM
and dont just say "put let_me_alone(); in the main process" I tried putting it before the loop and in the loop; it will only work for me if it is in the loop and there is nothing to signal it (so it is constantly doing let_me_alone() ;) and that's what I call a game-breaker. A new method will have to be created.
haha ok just give me some time to see your code. Would you zip it and upload here at its current state please?
ok
I got a couple problems now:
1. I have an enemy process and a player process together. The scroller follows the player, but when you jump onto that little platform above where the enemy moves back and forth under and then jump, the enemy freaks out.
2. If I make the z in the enemy process 1, then sometimes when I start the game up it will disappear but still register its active, so that means it's hiding behind the level somehow.
3. I noticed if I put a background image into tiled, it will not show up when the game is being played. Any way that I can set a background behind the tiles?
Anyways, I will leave this to you to solve, it seems the libraries could be upgraded if that is the problem. Thanks
thank you for attaching the example. Let me take a look to see if these are problems that can be solved at the library
Hey have you discovered anything?
I just moved to a new apartment and i'm waiting for the internet service :S
oh, well hopefully soon :)
have you been able to take a look at it?
Still without internet, I'm afraid it's going to take a week more -_-
so have you gotten a chance to look at it? i mean, you could download it to your phone and move it to the pc or go to the library and download it to a usb or something. this here data is crucial information that will further improve the library you have made and its just been sitting here going "daddy please fix me :'(". lol
Ok let me see what I can do. I might do what you're suggesting. Anyway, Internet service it's supposed to be installed on Monday. I'll let you know!
thanks! :)
I got some answers to your questions:
2. If I make the z in the enemy process 1, then sometimes when I start the game up it will disappear but still register its active, so that means it's hiding behind the level somehow.
Making the process z = 1 will send it to the back. You should set it to -1 so it won't be hidden behind the scroll render process.
3. I noticed if I put a background image into tiled, it will not show up when the game is being played. Any way that I can set a background behind the tiles?
It's not supported yet, but seems like a good idea, I'll implement it soon and set a project on bitbucket so it's easier to keep updated.
I got internet again, so tomorrow I'll by able to take a look at the first issue by the afternoon. Thank you for waiting.
thank you so much! ;D
Hey, I know what's the problem
Quote from: DoctorN on April 21, 2013, 03:31:34 PM
1. I have an enemy process and a player process together. The scroller follows the player, but when you jump onto that little platform above where the enemy moves back and forth under and then jump, the enemy freaks out.
There is one thing you have to know. The map is being rendered every time you move the position of your player, but the part of the map being rendered is the part visible on the screen (with one or two more tiles but it's pretty much only what you can see). This is done this way for memory optimization and performance.
What is happening actually is that when the enemy is outside the visible part of the map, and he checks for where is the floor for knowing where to move, the floor isn't there anymore, because it's outside the viewport and is not being rendered, it's black, so surely what is happening is that the enemy is falling because it doesn't have floor to stand on.
What you can do is to use the <a href="http://wiki.bennugd.org/index.php?title=Region_out">region_out</a> function. you can set a region of the size of the screen, or just to use the region number 0, and check in this way to know when the enemy is outside the viewport.
Once you know that, you can stop checking for the floor and wait until you are visible to start moving again.
Let me know if it makes sense
so do it like its done in the older games, where if its not on screen, itll go to its starting position? thanks
Yeah that's a possible solution.
What I would do is just to freeze the movement until the process is visible again:
loop
if (!region_out(id,0))
// do my stuff
end
frame;
end
But there is always the possibility to check the hardness against an image of the full stage. I think you can use Tiled to export the hardness layer of your map as an image. Once you load it to your game you can make your enemy to use it and to move independently if it's visible or not.
Of course it's not optimized in what it comes to memory usage. A common practice is to re-size the hardness map image to the 50% of its original size, so it'll require less memory to be loaded.When you do that, you need to divide your x and y positions by 2 in order to get the right color from the hardness map.
You are going to have to show me how to do it, because I tried this
//on-screen variables
write(0,128,32,0,"EnemyHP: "); write_var(0,192,32,0,eneHP);
//location on screen
x+=inc_x;
y+=inc_y;
IF(!region_out(id,0))
//gravity
if(grav_time>0)
grav_time--;
else
inc_y += gravity;
grav_time = grav_timer;
end
if(inc_y > max_vertical_speed)
// Change the max_vertical_speed value if you want to jump higher
inc_y = max_vertical_speed;
end
y_prev = y;
//moving
if(dir==1)
inc_x = 2;
else
inc_x = -2;
end
for(i = 0; i <= (enemy_dim_x/2); i++)
for(j = -(enemy_dim_y/4); j <= (enemy_dim_y/4); j++)
//right
collision_right=tilemap_get_pixel(map,0,x+i,y+j);
if(collision_right != RGB(255,0,0))
if(dir==1) inc_x = 2; end
else
if(dir==1) inc_x = 0; dir = -1; end
end
//left
collision_left=tilemap_get_pixel(map,0,x-(i+1),y+j);
if(collision_left != RGB(255,0,0))
if(dir==-1) inc_x = -2; end
else
if(dir==-1) inc_x = 0; dir = 1; end
end
end
end
//floor
for(i = 0; i <= (enemy_dim_x/2); i++)
for(j = -(enemy_dim_y/4); j <= (enemy_dim_y/4); j++)
collision_bottom=tilemap_get_pixel(map,0,x+j,y+i);
if(collision_bottom == RGB(255,0,0))
// Went through the floor, let's fix the position
y--;
inc_y = 0;
if(status == "in air")
status = "on ground";
end
end
end
end
//ceiling
for(i = 0; i <= (enemy_dim_y/2); i++)
for(j = -(enemy_dim_x/4); j <= (enemy_dim_x/4); j += (enemy_dim_x/4))
collision_top=tilemap_get_pixel(map,0,x+j,y-i);
if(collision_top == RGB(255,0,0))
y++;
if(inc_y < 0)
inc_y *= -1;
end
end
end
end
//getting hit
if(collision(type player_melee))
if(!hit)
hit = true;
hit_time = 15;
say("Enemy has been hit");
eneHP--;
end
end
if(hit_time>0) //after getting hit, the time between each time it can get hurt
hit_time--;
else
hit = false; //can be hit again
end
//health management
if(eneHP <= 0)
signal(id,s_kill);
end
END
//sprite section
switch(dir)
case -1:
graph = enemy_l;
end
case 1:
graph = enemy_r;
end
end
and the enemy process disappeared forever once it left the region, never to come back.
haha yeah that's because you should put
//location on screen[/size] x+=inc_x; y+=inc_y;
[/size]inside the if too[/size][/font]
I think you need to fix that lol, I put
IF(!region_out(id,0))
//location on screen
x+=inc_x;
y+=inc_y;
and it doesnt appear at all, it also makes the fps like 10 out of 60
Make sure you left the frame outside the if
the frame is outside the if, look at the code
process enemy(x,y);
private
//status
string status = "on ground";
int dir = 1;
byte eneHP = 10;
bool hit = false; //hit means it has been attacked
byte hit_time = 0; //the time before it can get hit again
//location
int inc_x = 0; // horizontal speed
int inc_y = 0; // vertical speed
//movement
int gravity = 1;
byte grav_time = 6;
byte grav_timer = 6;
int jump_height = -5;
int max_vertical_speed = 6;
int char_speed = 0;
int char_max_speed = 2;
//sprites
int enemy_r, enemy_l;
//collision
int collision_bottom = 0; // down collision
int collision_top = 0; // up collision
int collision_left = 0; // left collision
int collision_right = 0; // right collision
int i = 0;
int j = 0;
begin
z = -1;
ctype = c_scroll;
//upon startup it will either move left or right
dir = rand(0,1);
//load the sprites
enemy_r = load_png("enemy_r.png");
enemy_l = load_png("enemy_l.png");
loop
//on-screen variables
write(0,128,32,0,"EnemyHP: "); write_var(0,192,32,0,eneHP);
IF(!region_out(id,0))
//location on screen
x+=inc_x;
y+=inc_y;
//gravity
if(grav_time>0)
grav_time--;
else
inc_y += gravity;
grav_time = grav_timer;
end
if(inc_y > max_vertical_speed)
// Change the max_vertical_speed value if you want to jump higher
inc_y = max_vertical_speed;
end
//moving
if(dir==1)
inc_x = 2;
else
inc_x = -2;
end
for(i = 0; i <= (enemy_dim_x/2); i++)
for(j = -(enemy_dim_y/4); j <= (enemy_dim_y/4); j++)
//right
collision_right=tilemap_get_pixel(map,0,x+i,y+j);
if(collision_right != RGB(255,0,0))
if(dir==1) inc_x = 2; end
else
if(dir==1) inc_x = 0; dir = -1; end
end
//left
collision_left=tilemap_get_pixel(map,0,x-(i+1),y+j);
if(collision_left != RGB(255,0,0))
if(dir==-1) inc_x = -2; end
else
if(dir==-1) inc_x = 0; dir = 1; end
end
end
end
//floor
for(i = 0; i <= (enemy_dim_x/2); i++)
for(j = -(enemy_dim_y/4); j <= (enemy_dim_y/4); j++)
collision_bottom=tilemap_get_pixel(map,0,x+j,y+i);
if(collision_bottom == RGB(255,0,0))
// Went through the floor, let's fix the position
y--;
inc_y = 0;
if(status == "in air")
status = "on ground";
end
end
end
end
//ceiling
for(i = 0; i <= (enemy_dim_y/2); i++)
for(j = -(enemy_dim_x/4); j <= (enemy_dim_x/4); j += (enemy_dim_x/4))
collision_top=tilemap_get_pixel(map,0,x+j,y-i);
if(collision_top == RGB(255,0,0))
y++;
if(inc_y < 0)
inc_y *= -1;
end
end
end
end
//getting hit
if(collision(type player_melee))
if(!hit)
hit = true;
hit_time = 15;
say("Enemy has been hit");
eneHP--;
end
end
if(hit_time>0) //after getting hit, the time between each time it can get hurt
hit_time--;
else
hit = false; //can be hit again
end
//health management
if(eneHP <= 0)
signal(id,s_kill);
end
END
//sprite section
switch(dir)
case -1:
graph = enemy_l;
end
case 1:
graph = enemy_r;
end
end
frame;end
OnExit
say("enemy process has been killed");
unload_map(0,enemy_r);
unload_map(0,enemy_l);
end
the IF and END capitalized are the ones that handle the region_out. Sometimes it works, sometimes it doesnt. Both times, the game will either just leave a black window, or doing this will require so much it makes the framerate about 20 out of 60. So i am confused here S:l
first thing I noted is that you put a write inside a loop
YOU SHOULDN'T!!
that's why your framerate fell to the ground!
i tried that and thats not the case, the framerate only goes down when the code
IF(!region_out(id,0))
is being used, if
//location on screen
x+=inc_x;
y+=inc_y;
is outside it, then it will not show up at all. when it is inside it, it will appear every once in awhile. both times, it will throttle the framerate. Now, when it does appear, say you climb to the top and then fall down, you will see the enemy process randomly falling if it is within view as well, which makes no sense because it was on the ground.
do you compile the code or just look at it? i am really stuck here, and i need your help. thanks
Quote from: DoctorN on May 13, 2013, 08:07:07 PM
i tried that and thats not the case, the framerate only goes down when the code
IF(!region_out(id,0))
is being used, if
//location on screen
x+=inc_x;
y+=inc_y;
is outside it, then it will not show up at all. when it is inside it, it will appear every once in awhile. both times, it will throttle the framerate. Now, when it does appear, say you climb to the top and then fall down, you will see the enemy process randomly falling if it is within view as well, which makes no sense because it was on the ground.
do you compile the code or just look at it? i am really stuck here, and i need your help. thanks
let me just take a look as soon as I get home today. region_out is not a slow function. Shouldn't be the problem
have you taken a look?
http://www.youtube.com/watch?v=iwSHEb_JKNk (http://www.youtube.com/watch?v=iwSHEb_JKNk)
Loo, I've done the test and I don't experience any slow down. And works pretty fine, as expected:
This is the enemy with the chance I suggested
process enemy(x,y);
private
//status
string status = "on ground";
int dir = 1;
int eneHP = 10;
//location
int inc_x = 0; // horizontal speed
int inc_y = 0; // vertical speed
int y_prev = 0; //for collision
//movement
int gravity = 1;
int grav_time = 6;
int grav_timer = 6;
int jump_height = -5;
int max_vertical_speed = 6;
int char_speed = 0;
int char_max_speed = 2;
//sprites
int enemy_r, enemy_l;
//collision
int collision_bottom = 0; // down collision
int collision_top = 0; // up collision
int collision_left = 0; // left collision
int collision_right = 0; // right collision
int i = 0;
int j = 0;
begin
z = -1;
ctype = c_scroll;
//upon startup it will either move left or right
dir = rand(0,1);
//load the sprites
enemy_r = load_png("enemy_r.png");
enemy_l = load_png("enemy_l.png");
loop
if (!out_region(id , 0))
//location on screen
x+=inc_x;
y+=inc_y;
//gravity
if(grav_time>0)
grav_time--;
else
inc_y += gravity;
grav_time = grav_timer;
end
if(inc_y > max_vertical_speed)
// Change the max_vertical_speed value if you want to jump higher
inc_y = max_vertical_speed;
end
y_prev = y;
//moving
if(dir==1)
inc_x = 2;
else
inc_x = -2;
end
for(i = 0; i <= (enemy_dim_x/2); i++)
for(j = -(enemy_dim_y/4); j <= (enemy_dim_y/4); j++)
//right
collision_right=tilemap_get_pixel(map,0,x+i,y+j);
if(collision_right != RGB(255,0,0))
if(dir==1) inc_x = 2; end
else
if(dir==1) inc_x = 0; dir = -1; end
end
//left
collision_left=tilemap_get_pixel(map,0,x-(i+1),y+j);
if(collision_left != RGB(255,0,0))
if(dir==-1) inc_x = -2; end
else
if(dir==-1) inc_x = 0; dir = 1; end
end
end
end
//floor
for(i = 0; i <= (enemy_dim_x/2); i++)
for(j = -(enemy_dim_y/4); j <= (enemy_dim_y/4); j++)
collision_bottom=tilemap_get_pixel(map,0,x+j,y+i);
if(collision_bottom == RGB(255,0,0))
// Went through the floor, let's fix the position
y--;
inc_y = 0;
if(status == "in air")
status = "on ground";
end
end
end
end
//ceiling
for(i = 0; i <= (enemy_dim_y/2); i++)
for(j = -(enemy_dim_x/4); j <= (enemy_dim_x/4); j += (enemy_dim_x/4))
collision_top=tilemap_get_pixel(map,0,x+j,y-i);
if(collision_top == RGB(255,0,0))
y++;
if(inc_y < 0)
inc_y *= -1;
end
end
end
end
//sprite section
switch(dir)
case -1:
graph = enemy_l;
end
case 1:
graph = enemy_r;
end
end
end
frame;end
end
thanks, with the changes you made it doesnt slow down and it fixes the problem.
Try to compare both version to find out what was causing the slowdown. I'm curious now.
Quote from: DoctorN on May 17, 2013, 01:56:49 AM
thanks, with the changes you made it doesnt slow down and it fixes the problem.
BTW the only changes I made are the ones I suggested you
I see in lines 253 and 374 of api.inc that the z is set there. How does
for (i=0; i<map.layercount; i++)
layer = tilemap_layer_scroll(i, map.layers[i], map.tileset, width, height);
layer.x = graphic_info(0, 0, G_WIDTH)/2;
layer.y = graphic_info(0, 0, G_HEIGHT)/2;
SCROLL[i].z -= i;
viewport.layer_scrolls[i] = layer;
end
(lines 370-377)
work with
z = SCROLL[scroll_id].z;
(line 253)
cause my enemy will spawn, and I know it spawns, but sometimes it wont appear, so I think maybe its tucked back behind one of the layers.is the z -= i thing making the z negative like my player and enemy processes? do I need to change that to the - to a + or something? thanks