scrolling dodge 'em up

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

User avatar
Spoonweaver
Liquid Metal King Slime
Posts: 6466
Joined: Mon Dec 08, 2008 7:07 am
Contact:

Post by Spoonweaver »

What you want is a for command loop that runs through collision detection on every pixel and also pushes the player ahead one pixel at a time. Then have that for loop run a number of times equal to what you want the speed to be and put that loop inside your overall while command.

Also, if you're looking for pixel based movement... I feel I say this a lot... but I have an example of it in somekindaninja which is not only open to look at but open to freely use any part of for any reason. It also has collision detection.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Ah, your previous code only allowed the player to move once every 3 ticks, while what I posted allowed movement every 2 ticks.

A simple solution to add an extra one tick delay is to replace

Code: Select all

if &#40;abs&#40;queued move&#41; < move speed&#41; then &#40; 
with

Code: Select all

if &#40;queued move == 0&#41; then &#40; 
It would also be possible to combine the "input delay" variable, controlling when movement is allowed, with "queued move" for smooth movement.

What Spoonweaver is talking about is crucial if you have obstacles that are only a few pixels large/thick (fewer than the number of pixels you move in a single tick), or to prevent the player from being able to move past the corner of a block/wall without hitting it. (If you watch carefully, you should notice that your collision checking allows this if the player is never drawn overlapping the wall, which would trigger a collision, but would have overlapped if you consider the state in-between two frames). However, if the player sprite doesn't reach the corners of the 20x20 walkabout sprite, than that extra leeway when moving past corners would be desirable anyway.
Last edited by TMC on Tue Jan 17, 2017 3:41 am, edited 1 time in total.
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

After some testing, I think I am going to use my original script. The smooth movement looks great, but it feels slightly more sluggish because of the delay as the character slides from one tile to the next. I didn't think that it would make a difference, but it really does.

Sorry for spending your time unnecessarily. :(

I'm going to release a playable demo soon. If everyone disagrees with me, maybe I'll reconsider.
Last edited by Willy Elektrix on Thu Jan 19, 2017 4:42 am, edited 1 time in total.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

It's very hacky, but you can always make the position of the player's ship for the purpose of collision detection differ from its visual position... however of course that doesn't change how it feels, as least as long as you don't notice that you can clip through walls... so nevermind.
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

I'm still tooling around with this trying to get it to control better. I'm also debating whether to slow the scrolling speed down. When testing that, I noticed something.

The right side of the player sprite can intercept a wall for about 5-10 pixels without triggering the collision detection. Why is this exactly? The game scrolls to the right. Is there some conflict between the "slice velocity" command then the various collision detection statements?

Code: Select all

#####MAIN GAME SCRIPT#####
plotscript, movement, begin 

###Declares slices
variable &#40;playerslice, scrollslice, containerslice, deadslice, playerleft, playerright, playertop, playerbottom, pass, scrollspeed&#41;
playerslice &#58;= load walkabout sprite &#40;1&#41;
containerslice &#58;= load walkabout sprite &#40;0&#41;
scrollslice &#58;= lookup slice&#40;sl&#58;map layer1&#41;
set parent &#40;playerslice, scrollslice&#41;
set parent &#40;containerslice, playerslice&#41;
camera follows slice &#40;containerslice&#41;

#Determine if turbo/reverse zone
if &#40;level==4,or,level==8&#41; then &#40;
	set slice x&#40;containerslice, slice x&#40;playerslice&#41; +120&#41;
	put slice &#40;playerslice,0,80&#41;
	scrollspeed &#58;= 8
	set tag &#40;tag&#58;reverse, off&#41;
	show text box &#40;5&#41;
	wait for text box
&#41; else if &#40;level == 6&#41; then &#40;
	set slice x&#40;containerslice, slice x&#40;playerslice&#41;--120&#41;
	put slice &#40;playerslice,6780,80&#41;
	scrollspeed &#58;= -4
	set tag &#40;tag&#58;reverse, on&#41;
	show text box &#40;6&#41;
	wait for text box
&#41; else &#40;
	set slice x&#40;containerslice, slice x&#40;playerslice&#41; +120&#41;
	put slice &#40;playerslice,0,80&#41;
	scrollspeed &#58;= 4
	set tag &#40;tag&#58;reverse, off&#41;
	show text box &#40;4&#41;
	wait for text box
&#41;

###Set scrolling speed
set slice velocity&#40;playerslice, scrollspeed, 0&#41;

#####MAIN GAME LOOP#####
while &#40;check tag &#40;tag&#58;levelcomplete&#41;==off,and,check tag &#40;tag&#58;playerdead&#41;==off&#41; do &#40;

###Animate sprite
if &#40;animatedelay == 0&#41; then &#40;
	if &#40;get sprite frame &#40;playerslice&#41; == 0&#41; then &#40;set sprite frame &#40;playerslice,1&#41;
	&#41; else if &#40;get sprite frame &#40;playerslice&#41; == 1&#41; then &#40;set sprite frame &#40;playerslice,0&#41;&#41;
	animatedelay &#58;=6
&#41;
if &#40;animatedelay >> 0&#41; then &#40;decrement &#40;animatedelay, 1&#41;&#41;

###Player movement inputs
if &#40;inputdelay == 0&#41; then &#40;
	if &#40;key is pressed &#40;key&#58; down&#41;,or, key is pressed &#40;key&#58;s&#41;&#41; then &#40;
		set slice y&#40;playerslice, slice y&#40;playerslice&#41; + 20&#41;
		inputdelay &#58;= 8
	&#41;
	if &#40;key is pressed &#40;key&#58; up&#41;, or, key is pressed &#40;key&#58;w&#41;&#41; then &#40;
		set slice y&#40;playerslice, slice y&#40;playerslice&#41; -- 20&#41;
		inputdelay &#58;= 8
	&#41;
	if &#40;key is pressed &#40;key&#58; esc&#41;&#41; then &#40;#Open pause menu.
		open menu &#40;menu&#58;main&#41;
		inputdelay &#58;=12
	&#41;
&#41;
if &#40;inputdelay >> 0&#41; then &#40;decrement &#40;inputdelay, 1&#41;&#41;

###Collision detection
playerleft &#58;= slice edge x &#40;playerslice, edge&#58;left&#41; / 20
playerright &#58;= slice edge x &#40;playerslice, edge&#58;right--1&#41; / 20
playertop &#58;= slice edge y &#40;playerslice, edge&#58;top&#41; / 20
playerbottom &#58;= slice edge y &#40;playerslice, edge&#58;bottom--1&#41; / 20
if &#40;check tag &#40;tag&#58;reverse&#41; == off&#41; then &#40;#Moving forward
	if &#40;pass,and,westwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playerbottom&#41;
	pass &#58;= read pass block &#40;playerleft,playertop&#41;
	if &#40;pass,and,southwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerleft,playertop&#41;
	if &#40;pass,and,westwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playertop&#41;
	if &#40;pass,and,southwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playertop&#41;
	if &#40;pass,and,westwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerleft,playerbottom&#41;
	if &#40;pass,and,northwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerleft,playerbottom&#41;
	if &#40;pass,and,westwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playerbottom&#41;
	if &#40;pass,and,northwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playerbottom&#41;
	if &#40;pass,and,westwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	if &#40;pass,and,harmtile&#41; then &#40;set tag &#40;tag&#58;levelcomplete,on&#41;&#41;
&#41; else &#40;#Moving reverse
	pass &#58;= read pass block &#40;playerleft,playertop&#41;
	if &#40;pass,and,southwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerleft,playertop&#41;
	if &#40;pass,and,eastwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playertop&#41;
	if &#40;pass,and,southwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playertop&#41;
	if &#40;pass,and,eastwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerleft,playerbottom&#41;
	if &#40;pass,and,northwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerleft,playerbottom&#41;
	if &#40;pass,and,eastwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playerbottom&#41;
	if &#40;pass,and,northwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	pass &#58;= read pass block &#40;playerright,playerbottom&#41;
	if &#40;pass,and,eastwall&#41; then &#40;set tag &#40;tag&#58;playerdead,on&#41;&#41;
	if &#40;pass,and,harmtile&#41; then &#40;set tag &#40;tag&#58;levelcomplete,on&#41;&#41;
&#41;

#####END OF MAIN LOOP#####
wait &#40;1&#41;
&#41;
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Why did you write "slice edge x (playerslice, edge:right--1)"? You can't subtract a value from 'edge:right', it's a special value. Unfortunately edge:right--1 is equal to edge:center, so it didn't show an error.

Also, if you wanted, you could replace the collision detection with the new "check wall collision x/y" commands, but you would still need to check the harmtile bit yourself. And there is a bug in those commands, as I wrote in the 'micro-blog' thread, so maybe it's not a good idea right now.
Last edited by TMC on Wed Feb 01, 2017 11:21 am, edited 1 time in total.
User avatar
Willy Elektrix
Liquid Metal Slime
Posts: 910
Joined: Sun Aug 15, 2010 11:30 pm

Post by Willy Elektrix »

TMC wrote:Why did you write "slice edge x (playerslice, edge:right--1)"? You can't subtract a value from 'edge:right', it's a special value. Unfortunately edge:right--1 is equal to edge:center, so it didn't show an error.

Also, if you wanted, you could replace the collision detection with the new "check wall collision x/y" commands, but you would still need to check the harmtile bit yourself. And there is a bug in those commands, as I wrote in the 'micro-blog' thread, so maybe it's not a good idea right now.
Thanks! I read about the "check wall collision" command already. I was debating whether to change the script to use it.
Post Reply