Thanks for taking the time to read this.
Right now I'm making a really basic tile based game. The map is a large amount of 16x16 tiles, and the character image is 16x16 as well. My character has its own class that is an extension of the sprite class, and the x and y position is saved in terms of the tile position.
To note I am fairly inexperienced with pygame.
My question is, I am planning to have character movement restricted to one tile at a time, and I'm not sure how to make it so that, even if the player hits the directional key dozens of time quickly, (WASD or arrow keys) it will only move from tile to tile at a certain speed. How could I implement this generally with pygame? (Similar to game movement of like Pokemon or NexusTk). One movement would result in a player being in a tile. They couldn't stop halfway between tiles for example.
Thanks for your time! Ryan
You store your characters location as a grid coordinate. So if he's at (2,0) he is rendered at (32,0). The game then animates him moving between tiles, but, he's either on one or the other. While in the move state, you render an (x,y) offset between 0 to tilewidth.
It sounds like you want one move per keypress, if time elapsed / animation has completed. So:
On keypress, toggle to: animating state
Set destination tile coordinate
draw offset, between 0 and tilewidth, depending on time elapsed. offset = (elapsed_ms / 1000.) * tile_w would scale between 0 to 16 if time is less<= 1 second.
Once time elapsed is >= animation length (I chose 1000. above), switch to stationary state.
If keypress happens while in animation state, ignore it.
Pygame example: using numpy for map array.
Related
At the program start, you should disable all turtle animations and make the turtle hidden. Next your program should implement the following requirements.
Prompt the user for a couple of inputs, the grid size N and a difficulty level between 1 to 3.
Draw an N × N grid as shown in this figure. Put the game title, start button and score on the top.
Handle mouse clicks in the turtle window. Clicking on the start button should, well, start the game but other clicks should be ignored.
Implement the gameplay, which includes displaying ten squares on the grid one after the other. Display the current square number (1 to 10) at the top. Each square should occupy a random box on the grid. A square would only stay on screen for a period of 2, 1.5 or 1 seconds, corresponding to difficulty levels of 1, 2 and 3 respectively.
Let the user play the game with mouse. Objective of the game is to shoot (click) as many squares as possible. A hit increases the score and a miss deducts the score by one. Only the clicks inside grid boundaries should be entertained. If a square is successfully hit, its colour should change to give user an indication of success.
Once the time is elapsed for all ten squares, replace the box number at the top with the ‘finished’ label.
Note that turtle graphics do not provide support for erasing a part of drawing (or text). To mimic erasing, you should repaint the desired area with a white (or whatever your background color) filled rectangle.
To show and hide the target squares at regular time intervals, do not use a loop. This job can be managed via task scheduling as shown below in the sample codes.
Constraints
You can only import the following library modules: turtle, threading, random, math, sys
In many online examples of turtle graphics applications, multiple turtle objects are used on the same window. You are NOT allowed to proceed that way. Use a single turtle for all drawings.
You should follow good programming practices, for example using named constants, creating several reusable functions (top down design) and minimizing the use of global variables. A few global variables will be essential though, for example, to store the data required by multiple functions.
Suggested dimensions and locations of elements
Window size: 750 × 800
Grid Size: 700 × 700
Bottom left corner of grid: (–350, –375)
Size of target squares: Depends on size of a grid box. Leave 10 pixels margin around sides, so that squares do not touch the grid lines.
Game title text location: (–350, 345) left aligned
Start button / current square number location: (0, 345) centre aligned
Score display location (350, 345) right aligned
I am making a scrolling background type of game, kind of like Mario. I have a character that walks on the ground and can go left or right, and I want to introduce a flying eyeball that is suspended in the sky that follows the character's movements. I have an eyeball png (the eye of chuthulhu from Terraria). All I want it to do is rotate based on where the character is, and seem to stare at it (the next step is to have it shoot lasers at the character). How would I do this? Thanks in advance.
You could use the PyGame function pygame.transform.rotate() or pygame.transform.rotozoom() to pre-create rotated versions of your eyeball.
It sounds like the eyeball will pass over the top of the player when the player changes walking directions (since it's always following). So simply comparing the difference in sideways-position between the player and the eyeball should be enough to determine which of the pre-rotated eyeball images to choose.
If the eyeball's X co-ordinate is a long way from the player, then a slight angle is needed. As the player gets closer to having the eyeball above them, the angle should change to the point where the eye is looking straight down. This corresponds to the difference between the eyeball-X and player-X being small (tending towards zero).
Maybe even a simple mapping table between X-difference and sprite-image would be enough.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
For a project I want to do for my class' Pygame final, I want to make The Legend of Zelda: A Link To The Past. However right when I started I realized that the scrolling would be quite an issue.
How do you implement a scrolling technique that follows the player until the edge of a map or image but still allows the player to move closer to the edge?
A reference because I feel as if I am not correctly wording myself:
https://www.youtube.com/watch?v=kWyT9d8CiKY
My personal idea was to use a switch that switches the background image moving to Link's image moving.
A major component of any branch of engineering is breaking down big problems into smaller ones. So let's break down your problem.
How would you design a scrolling technique that follows the player
until the edge of a map or image but still allows the player to move
closer to the edge?
Okay, so there are three problems here. Moving the player sprite, moving the background sprite, and working out when to do each. Moving the player sprite is pretty straight forward - give it an (x,y) coordinate on the screen and move that according to the input controls (keyboard/mouse/etc).
Now let's consider the background sprite. For simplicity we'll assume that your whole background can be loaded as one big sprite. We want to render a portion of that background onto the screen - so we need to maintain the position of the background relative to the screen with it's own coordinates.
You can think about this two ways - either the screen stays stationary and the background moves behind it, or the background stays and the screen moves. Given that you'll eventually be tracking lots of other items (baddies, treasure, etc) and their position on the map, I would suggest thinking about everything moving relative to the background (even though this may seem less intuitive at first). Let's call this the world coordinate. To render things to the screen we'll need to work out their screen coordinate.
Okay, so we now have two coordinates - the positions of the screen and the player. For consistency, let's make the player position use world coordinates too.
So how do we render this to the screen? Start by listing out the rules:
the background should always fill the screen (i.e. don't scroll so far
that you can see outside of the background sprite)
the player should be centred on screen, except when that would violate #1
So the position of the screen is dependent on the player, but with some limits depending on where it is on the map. Let's consider the x coordinate (note this is untested):
# start by centring the screen on the player
screen_x = player_x - screen_width/2
# limit the screen to within the bounds of the background
if screen_x < 0:
screen_x = 0
if screen_x > (background_width - screen_width):
screen_x = (background_width - screen_width)
You can now calculate the render position of the player (position on screen) by subtracting screen_x from player_x. The background render position is calculated the same way (but should result in a negative coordinate).
So I'm trying to figure out how to make a bullet class move from character to mouse click and if it hits a monster it will do damage to a monster. I've figured out how to calculate the mouse position and character position. It has been a while since ive been in a math class.
i'm using pygame, python 3.4
A possible solution could be to find the slope of the line between the point of origin(where you are shooting the bullet from) and the location of the mouse click. If you are storing the bullet's x and y values you can then use the slope to change those values every clock tick depending on the speed of the bullet or however you've got it working.
Ex. If the slope of the line is 2/5, every tick you change the bullet's y by 2 and the bullet's x by 5.
I think this may work, or at least may be close to what you are looking for.
I'm currently making a 2D side-scrolling run'n'jump platform game in PyGame. Most of the stuff is working OK and very well in fact - I am exploiting the fast pyGame Sprite objects & groups.
What I'm interested to know is how people usually deal with Rects for scrolling games. I obviously have a level that is much bigger than visible area, and the player, enemies, bullets etc each have their own (x,y) coordinates which describe where they are in the level.
But now, since we use the "spriteGroup.draw(surface)" call, it will not display them in the right spot unless each objects Rects have been adjusted so that the right part displays on the screen. In other words, everytime a player/enemy/bullet/whatever else is updated, the Camera information needs to be passed, so that their Rect can be updated.
Is this the best method to use? It works but I don't really like passing the camera information to every single object at every update to offset the Rects.
Obviously the ideal method (I think) is to use Rects with "real" coordinates, blit everything to a buffer as big as the level, and then just blit the visible part to the screen, but in practice that slows the game down A LOT.
Any comments/insight would be appreciated.
Thanks
You could extend de Sprite.Group so it recives the camera information.
Then do one of these options:
A. Override the update method so it updates the on-screen coordinates of every sprite.
B. Override the draw method so it updates the on-screen coordinates of every sprite and then calls its parent draw method.
I think A it's easier and cleaner.
I don't really like passing the camera information to every single
object at every update to offset the Rects.
Camera may be global, or, a member of a global Game() class instance. Then your sprite class's draw method doesn't need an argument.
You can override draw yourself, so it does:
dest = game.camera.topleft + self.rect.topleft
screen.blit( self.surface, dest )
This keeps the bullet's rect in world-coordinates, yet blits using screen-coordinates.
One method I found is to keep track of a scrollx and a scrolly. Then, just add scrollx and scroll y to the coordinates when you move the rectangles.
You can have a 2 variables level_landlevel_d which see where you are in the level, Then check which sprites are in the visible area
level_d+height and level_l+width,
and draw them on the screen.
The simple way to do it is like that:
Create a CameraX and CameraY variables, and when you blit objects on the screen use this:
blit(surface, (x -CameraX, y -CameraY))
any object that gets affected by the camera should be drawn like that, but keep in mind that there are objects that you may want to remain uneffected (like health bars or status windows)
just keep in mind everytime you want to move camera do this
#Move Camera Right
CameraX += 10
#Move Camera Left
CameraX -= 10
#Move Camera Down
CameraY += 10
#Move Camera Up
CameraY -= 10
Just keep in mind that if they get negative values they may not work correctly, also you must probably define some limits (you dont want your camera to move over the limits of your map