Sprint #2.5 - Daily Scrum #04
Product: Tetris2P AI
Sprint Summary
Daily Objectives
- Set up clickable objects
- Make an example or wrapper class for clickable gameObjects
Notes
“”” onkeypress : invokes JavaScript code when a key is pressed onkeydown : invokes JavaScript code when a key is held down (but not yet released) onkeyup : invokes JavaScript code when a key is has been released after being pressed. “””
Keydown event triggers continuously while its being held down Only removes a keystate from its active state on key up, but this doesn’t work when a user clicks off the canvas/screen
So let’s come up with conditionals for assuming a key is being held down. Currently, when a key is being held down:
- We start a timer from the initial keydown event
- The keydown event keeps firing periodically
We want to be able to use the timer for input events, rather than the keydown event. We want developers to be able to differentiate press and hold input for games. In my case, I want to play around with the speed at which pieces move left and right and control the ‘slipperiness’. When a person clicks off the screen while a button is being held down, the keyup function doesn’t trigger, which is meant to stop the keydown event, but the keydown event will stop firing when you tab back in. Essentially the only indicator that the user tabbed out during a long press is that the keydown event stops firing. So, we need a way to somehow remember the last time the keydown event was triggered. If the time period between them is too large, we can assume that the key is no longer being held down. So we can add a counter for tracking that. When a keypress is detected, reset that counter to 0. Before adding a delta to the timer, increment the counter. If the counter becomes > n, then we assume the keypress function has stopped firing and the button is no longer being held. Then we just delete the entry.
Ok! So that works now :) one tidbit though is that if you click back on the screen it starts a new keypress action? Should I leave that part as is? Yeah I think so? When a user is holding down a key and tabs back in, it automatically assumes the action. I’m gonna assume its fine for now, since it has nothing to do with the misreading key hold presses.
Cool! Wait heck there’s a bug. My previous code now makes this an issue. The keydown event keeps firing periodically ONLY for the most recent keydown press, so the other keys aren’t able to refresh the update counter and they get deleted from the input list. I definitely want to have the failsafe of the update counter. But I can’t have it misfiring inputs. What are possible solutions I can do? Issues:
- keypress only continuously fires for the most recent keypress event
- engine won’t detect key release if you click outside of the window or change tabs
The first bullet point depends on the second bullet point. This is relevant in some cases where a player might want to move a character diagonally upwards, and holds down the up + right arrow keys. Currently, the up movement will working, but the right movement will stop. This case only comes up when there’s multiple keys being pressed down. Maybe I should check if there are any other keys that are still being held down? I could also just generalize it to only one integer? YES this can work. Instead of a dictionary, just make it an integer variable and maybe raise the failsafe value.
Having just a single integer is working good. I’m gonna change it so it only increments once per update loop, cause its buggy when too many keys are being pressed at once.
What’s next now! :D
I should reiterate what I have now? I think I have this written down somewhere else already. Nvm guess I don’t
Here’s a backlog/to do list:
- Decide on/if we want to include premade components
- Clickable elements
- Moveable elements
- Timer element
- networking (client server code?)
What features am I missing to implement my tetris game? Shit its gonna be weird when I wanna deploy this for client/server. Should I discuss what steps I have to do for that? I think the server just needs to run the update loop, while the clients run their update+draw loops. Or mostly just preemptive draw loops. I wonder if there’s an easy way of doing this without changing the game code. Usually the server contains code that some client’s don’t know about. But we can outline the main parts of a networked game:
- draw functions (only client side)
- Input functions (only client side)
- client update functions
- Similar to server update function except with limited information
- Client update should be hard fixable using screenshot sent by server
- server update functions
- Similar to client update but holds extra networking information
I think we should make some set components though? What are some good example/necessary components for game dev? I can check unity real quick lmao, sec:
- physics2d area
- sprite + sprite animations
- clickable area
- ‘rect transform’
- determines position of the element
- can probably combine with a different component?
- audio component
I’m not doing everything above I think? But its good to keep them in the back of my mind. I’m concerned whether or not I want to include a world space, making the canvas the ‘camera’. Each scene would then have multiple cameras, that you can switch between. How would I implement walking around a world space, with a minimap showing in the bottom corner? The minimap would be a ‘fixed UI’ gameElement, with reference to the scene, and a list of gameObjects to reference. The minimap has access to pointers to other objects, and the details of how to render them on itself. I think the world map itself should be a gameElement of the scene rather than the scene itself. For now we can assume we render every existing object in the scene.
I think we move the anchor point of the worldMapObject around in order to render it within the canvas. This only needs to be implemented in the draw function. Characters and other GameObjects can be drawn relative to the worldMap. Also have physics associated with the worldMap.
In regards to networking, I’m still concerned with how ‘lobbys’ and stuff work on a networking scale. I think I just have to do more game networking research in general and server management.
So let’s continue talking about components? Its weird thinking about it since, the developer should already be programming the game object in an editor rather than a UI.
I should draw this out? The physics engine is only gonna be ONLY rectangles
Collision Detection
- Axis Aligned Bounding Boxes
Impulse Resolution
Simple Manifold Generation
I’m only gonna be using AABB vs AABB detection (no circles!), to make things easier :) How do you optimize it? General tactics include sorting or aligning objects to a grid and only checking the surrounding areas.
For a single collision check. Judging by this, I think we should run the update loops, and then collision detection loops (in the engine code), and then a resolve collisions thing? Also once we detect a collision, we can add two entries to the collision dictionary.
AABB Tree Collision Detection
- Kinda of only works when you’re checking one moving object
- Builds a tree as you create objects
- Wraps pairs of objects in a pseudo box, so when an object doesn’t collide with the pseudo box, then it doesn’t collied with any of the objects within it.
- Some random ideas:
- Create list of static moving game objects
- Game objects with deterministic movement, pad their pseudo box to fill all of their predicted movement
- Create an AABB tree for each gameobject/player character that moves freely
- Collision detect all player characters with each other
Initial collision detection ideas sound pretty promising, but I’m still not sure how to incorporate it into the engine.
It suffices to just record the position of the click, and then the clickable UI objects can check for themselves if they’ve been clicked.
What happens if a UI element being clicked triggers a scene change? I’d need to cancel the update loop then?
For a gameObject to switch the scene, they need to:
- set the engine.currentScene value directly to the new scene.
- pass arguments to the new scene
- set engine.prevScene
- delete prevScene object to save memory probably on the next update loop
After the prevScene finishes its update loop, we can have it be deleted in the end() function. On the next update loop, the new scene should be instantiated already and update normally.
So for to do list order right now:
- Set up clickable objects
- Set up scene transitions
- Set up aabb physics
- Make Tetris?
- Set up networking
- Make a mini MMO?
- Make the Tetris AI still
Objectives Completed
-
added keypress and click detection on the canvas along with timers and positions
-
started researching how to handle collision detection with AABB’s
-
fixed issue with onkeyup events not registering when windows/tabs