I am currently coding a basic snake game in processing and I want the snake not to move in the opposite direction it is currently moving.
The snake just stops whenever I press the opposite direction but i want the game to ignore the keypress.
if (keyCode == DOWN && direction != "up"){
if (frameCount % framespeed == 0){
ypos += speed;
}
direction = "down";
}
if (keyCode == UP && direction != "down"){
if (frameCount % framespeed == 0){
ypos -= speed;
}
direction = "up";
}
if (keyCode == RIGHT && direction != "left"){
if (frameCount % framespeed == 0){
xpos += speed;
}
direction = "right";
}
if (keyCode == LEFT && direction != "right"){
if (frameCount % framespeed == 0){
xpos -= speed;
}
direction = "left";
}
Just ignore the frameCount
First off, you should not use == or != to compare String values. You need to use the equals() function. You've mentioned that you tried this in the comments, but then please update your post to include a new MCVE. Note that this should not be your full snake game. It should be a minimal example. For example, come up with a simple sketch that shows a direction on screen (in text, not something moving). Change the direction with the arrow keys. Make it so you can't change the direction to the opposite.
Another thing you need to consider is that if the snake is pointing up, the user can press right and then down to reverse the direction of the snake. If they do that fast enough, it will happen faster than your frame rate, and the snake will reverse direction.
There are a number of ways to fix this, and Stack Overflow isn't really designed for general "how do I do this" type questions. It's for specific "I tried X, expected Y, but got Z intsead" type questions. So please break your problem down into smaller steps and debug your code so you understand exactly what's happening. If you still can't get it figured out, then post a MCVE in a new question post and we'll go from there. Good luck.
Related
I had a script somewhat similar like in this video:
extends KinematicBody2D
var movement=Vector2();
var up= Vector2(0, -1);
var speed=200;
var isAttacking=false;
func _process(delta):
if Input.is_action_pressed("ui_right") && isAttacking == false:
movement.x = speed;
$AnimatedSprite.play("walk");
elif Input.is_action_pressed("ui_left") && isAttacking == false:
movement.x= -speed;
$AnimatedSprite.play("Walk");
else:
movement.x = 0;
if isAttacking == false:
$AnimatedSprite.play("Idle");
if Input.is_action_just_pressed("Attack"):
$AnimatedSprite.play("Slash");
isAttacking=true;
movement = move_and_slide(movement, up * delta);
func _on_AnimatedSprite_animation_finished():
if $AnimatedSprite.animation == "Slash":
isAttacking= false;
but the problem was when I was rapidly pressing attack & movement on my keyboard
sometimes the isAttacking did not get set back to false after the animation was completed and hence froze my character animation
Maybe it was a bug in invoking the connected signal function when pressed rapidly? but anyhow it gave me a nightmare
so I came up with this workaround for rapid key pressing attack and movements (check the solutions) so no one else has to go through what I did :)
Instead of checking for attack in _process() I used _unhandled_key_input() and this seemed to get rid of the problem
Hope this helps! :D
...
func _process(delta):
if Input.is_action_pressed("ui_right") && isAttacking == false:
movement.x = speed;
$AnimatedSprite.play("walk");
elif Input.is_action_pressed("ui_left") && isAttacking == false:
movement.x= -speed;
$AnimatedSprite.play("Walk");
else:
movement.x = 0;
if isAttacking == false:
$AnimatedSprite.play("Idle");
if Input.is_action_just_pressed("Attack"):
$AnimatedSprite.play("Slash");
isAttacking=true;
movement = move_and_slide(movement, up * delta);
func attack_animation_finished(var _extra):
isAttacking=false
func _unhandled_key_input(event):
if(event.echo):
return
if(!event.pressed):
return
if(event.scancode==KEY_X and !isAttacking): # x key to attack (you can use whatever you like)
isAttacking=true
if!($AnimatedSprite.is_connected("animation_finished",self,"attack_animation_finished")):
$AnimatedSprite.connect("animation_finished", self, "attack_animation_finished", [], CONNECT_ONESHOT) # warning-ignore:return_value_discarded
$AnimatedSprite.play("Slash");
Note: I haven't ran this particular code segment but I have used this logic/approach in a working larger script which would be too long to share here
So I'm trying to make a ball hit the wall and bounce off it just like pong game. but for some reason when ball thinks the canvas is smaller that it actually is.
here is my onDraw code:
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
if (flag) {
x = (int) canvasWidth;
y = (int) canvasHeight;
}
else
{
if (goingRight)
x=x+5;
else
x=x-5;
if (goingDown)
y=y+5;
else
y=y-5;
}
canvas.drawBitmap(ball,x/2,y/2,null);
if (x>canvasWidth)
goingRight=false;
else if (x<0)
goingRight=true;
if (y>canvasHeight)
goingDown=false;
else if (y<0)
{
goingDown=true;
}
flag=false;
Couldn't find a fix for it. anyone knows what is the problem?
Probably because you draw your ball at half x and half y.
canvas.drawBitmap(ball,x/2,y/2,null);
I think you want draw the ball not on top/left corner of the bitmap but on center.
Is not tested ! Try somthing as...
canvas.drawBitmap(ball,x - (ball.getWidth()/2),y - (ball.getHeight()/2),null);
Hello I am trying to limit how much a user can drag within Gamemaker.
I have created two views within a room.
The first view is the full room width and size 1250x768
The second view is the area which i would like the user to be able to zoom into and drag which is 955x465. x and y position is 40 by 170.
Currently i have set up the zoom for the second view which is:
vmx=(mouse_x-X)-omx;
omx=(mouse_x-X);
vmy=(mouse_y-Y)-omy;
omy=(mouse_y-Y);
if mouse_wheel_up() && view_wview[1] > 600 {
center_of_space_x=view_xview[1]+view_wview[1]/2;
center_of_space_y=view_yview[1]+view_hview[1]/2;
view_wview[1]-=view_wview[1]*0.15;
view_hview[1]-=view_hview[1]*0.15;
view_xview[1]=center_of_space_x-view_wview[1]/2;
view_yview[1]=center_of_space_y-view_hview[1]/2;
}
if mouse_wheel_down(){
view_xview[1] = 40;
view_yview[1] = 170;
view_wview[1] = 955;
view_hview[1] = 465;}
Below is the code for the drag:
if (mouse_check_button_pressed(mb_left)) {
drag_x = mouse_x
drag_y = mouse_y
}
// update:
if (mouse_check_button(mb_left)) && view_wview[1] < 700 {
// actual dragging logic:
view_xview[1] = drag_x - (mouse_x - view_xview[1])
view_yview[1] = drag_y - (mouse_y - view_yview[1])
// make sure view doesn't go outside the room:
view_xview[1] = max(0, min(view_xview[1], room_width - view_wport[1]))
view_yview[1] = max(0, min(view_yview[1], room_height - view_hview[1]))
So the limit works for the view to not leave the room but i want it not to leave the specific view which has been set up.
Please help
I have modified my code to use a clamp function which works but it is not a clean solution:
view_xview[1] = clamp(view_xview[1],40,400);
view_yview[1] = clamp(view_yview[1],170,500);
The user has to be fully zoomed in to have the view restricted. If he is not then they can still see other areas of the room :(
EDIT: I may have misunderstood your question, I will leave the below code for reference if it helps you solve the problem a bit differently.
I would probably check that mouse_x and mouse_y are not outside the view you want.
if (mouse_x > view_limit_x || mouse_y > view_limit_y)
{
return; // Or continue or break however your language of choice goes.
}
If you cannot do a return statement, wrapping your code in a reverse logic of above should work fine.
Old Post:
I am not 100% familiar with game maker. I would implement something like this by skipping the drag logic every x frames. Say you are updating at 60fps, and you want the drag to be 6 times slower, you just need to only update the logic 10 x per frame.
const int framesToSkip = 6;
int frameCount = 0;
update()
{
// Will only call when framecount = 0, 6, 12, 18 etc.
if (frameCount % framesToSkip == 0)
{
// Drag Logic.
}
frameCount++;
}
This way drag logic only occurs 1/6 the rate as before. You could also change this around to happen the first x amount of frames and then skip for the rest (but this may appear a bit choppy).
As you see in the picture above, billy, our little orange dressed man, is going off the screen to the left and appearing on the right side.
This is what I want to happen, however, I can't seem to replicate this effect (I got the picture with some modifications in Paint.net).
Basically, if the players x position is negative, it should wrap to the other side. If the x is larger than the width, it should wrap over to the left side.
Draw it two times when you need it.
void Draw(SpriteBacth batch)
{
batch.Draw(Player.texture, Player.Position, player.Source, player.Color);
if (Player.X <0)
{
bacth.Draw(Player.texture, Player.Position + ScreenHorizontalSize, player.Source, Player.Color);
}
else if (Player.X + Player.Size.Width> ScreenHorizontalSize.Width)
{
bacth.Draw(Player.texture, Player.Position - ScreenHorizontalSize, player.Source, Player.Color);
}
}
void Update()
{
if (Player.X < -Player.Size.Width) Player.X += ScreenHorizontalSize.Width;
if (Player.X > ScreenHorizontalSize.Width) Player.X -= ScreenHorizontalSize.Width;
}
Of course you have to take in mind this when you check for colliding with player, you will have to check in the two positions too.
I'd like to bottom-align cells in a tiled DataGroup, so that rows grow bottom-top instead of top-bottom. I guess what i'm looking for is something like RowAlign.BOTTOM, but that doesn't seem to exist.
Rows should have fixed heights and gap, so RowAlign.JUSTIFY_USING_GAP and RowAlign.JUSTIFY_USING_HEIGHT won't work for me.
Any hints?
Yes i want to answer my own question. What i wanted to do was extend TileLayout and override updateDisplayList(), but due to excessive use of privates in TileList that was not possible so i ended up copying the whole TileList source and changed a few lines in updateDisplayList(), eg:
var yPos:Number = unscaledHeight - visibleStartY - _rowHeight;
and
yPos -= yMajorDelta;
and
// Move along the minor axis
if (++counter >= counterLimit)
{
counter = 0;
if (orientation == TileOrientation.ROWS)
{
xPos = 0;
yPos -= yMinorDelta;
}
else
{
xPos += xMinorDelta;
yPos = unscaledHeight - visibleStartY - _rowHeight;
}
}
a hack, sort of, but works fine for my needs.