I need some help working out the class hierarchy for a game I'm developing with JavaScript. The game is a top-down space shooter with (at its basic level) a background, player, bullets and enemies.
I've come up with a class diagram which I think needs to be improved on:
Nothing out of the ordinary here, the main class is called Cosmos (the name of the game) which has a tick() method which fires at roughly 60 times per second. The Background, Player and Enemy classes belong to Cosmos and the Bullet class belongs to the Player class, because a Player "owns" Bullets.
There is one major problem that comes to mind with this diagram though, and that is how I'll do collision detection between the players bullets and the enemies. I could write a method in the Player class to pass a bullet's x and y to Cosmos and do the collision detection in Cosmos, but that doesn't seem like the best way to do it. Would doing the collision detection in Cosmos be okay if I'm going for a neat, organisable approach?
Any other modifications you could make to make my life easier is also greatly appreciated.
Your diagram seems to have some issues. You wrote:
The Background, Player and Enemy classes belong to Cosmos and the Bullet class belongs to the Player class, because a Player "owns" Bullets."
This suggests an aggregate or composite relationship, but in your diagram you use inheritance arrows... You have Player extending Bullets, and multiple inheritance on Cosmos, which extends Player, Background, and Enemy. Also, your diagram is upside down; generally base classes go at the top.
If you want to use inheritance chains, consider something like this instead:
The job seems way too small for worrying that much about class hierarchies.
In any case, Java-style classes is just one way of segregating code, keeping a reasonable order and appropriate comments can do virtually the same thing.
In short, just put Bullets directly below Cosmos, it is not that big a deal.
Related
Purpose: I want to create a game like this one
Problem: How to make it so that when dragging an item it does not go beyond the borders of the cell? I can do it like this, but you can easily control it from the keyboard, but somehow I’ll find it difficult to work with dragging. In other words, it is required that dragging an item is only possible along a particular path (as in the example of the game above)
Any thoughts? Any options and solutions are welcome. Thanks!
Judging by the example you gave you can do this by placing the walls around the item. Whenever the system detects collision with the walls movement of the item will stop. I have mostly used this functionality with Unity Engine so i am afraid i can't provide you with specific codes.
Check this video: https://www.youtube.com/watch?v=hNV-xEMALr8
I think you will be able to figure this out after watching it.
I'm messing around with Phaser 3 in an es6 syntax. In Phaser 3 everything is now composed of Scenes, where you load/update/etc everything. So, for the primary Game scene, I extend Phaser.Scene.
export default class Game extends Phaser.Scene {
preload()
create()
...
But let's say I have a player, which will involve 100's of lines of code that I would like to keep in a separate file for code cleanliness. How do I organize that?
Every tutorial/info I find about it just includes all of the code for the scene in the same file, but this is obviously not realistic for fully fleshed-out games. I want to separate many elements of the game into their respective classes/files.
So, I just create a player class, that doesn't extend anything? Or should I extend it by something like Phaser.Sprite?
I think the reason most tutorials throw everything in one file is because:
they're geared towards beginners, who may be experiencing programming for the first time and therefore might get confused by working with multiple source files
fun games in Phaser can definitely be created in one source file
some game hosting platforms want/prefer a single JS file
To answer your specific question "So, I just create a player class, that doesn't extend anything? Or should I extend it by something like Phaser.Sprite?", it depends.
I'm working in TypeScript, so my structure and code is a bit different, but I have a src directory structure like the following:
assets
ts
Prefabs
Scenes
Game.ts
In the ts/Scenes directory I throw all of my scenes, that extend Phaser.Scene. In the ts/Prefabs directory (prefabs is something I picked up years ago from a Phaser 2 tutorial) I put any custom classes.
Looking at the game I'm working on now, I have one that extends Phaser.GameObjects.Group, three that extend off of that custom object, and then a couple that don't extend off of anything. In the past I've extended off of Phaser.Sprite as well.
The real question of whether to extend off of Phaser.Sprite or not is based upon what you want the object to do for you.
In my case I wanted to create a basic Character class that my Hero and Monster instances could extend, and that would create sprites within the game when I created them. I opted for a Group because the sprites I'm using consist of two parts, so with a Group I could add both Sprites to it when I created the object, but could have gone with a Sprite had I just needed one asset.
One of my other custom objects just stores information about the game state, so since there's nothing that actually needs to display in game when it exists, it doesn't extend anything in Phaser.GameObjects.
So the question for you is, when you create a new Player, do you want it to display as a Sprite with additional functionality/properties, or not? If the former, extend Sprite (or whatever Phaser.GamesObjects you need to. Otherwise don't.
Maybe you can try nkholski/phaser3-es6-webpack.
I'm currently developing a game this way.
I am developing a room in threejs and there are lot of models like sofa, walls, floor, curtain, rug, table, wall-panel, etc. (all are 3ds max models). So my problem is the controls are not smooth, I have tried orbital as well firstPersonControls but all are getting janked while operating. Please help?
You should try to reduce the models details of the mesh in favor of providing details in the texture map images (bump map etc.).
Basically you can load initially low quality models and if the frame rate is still good (maybe 20 fps and up) start adding in the more detailed versions.
If it's really bad, notify them they should try it on a faster device or desktop.
If this is on your fast machine/device, then try one model at a time to isolate when or where there's something else going on that's wrong.
Otherwise I'm sure there's a handful of features to disable from double-sided to aliasing etc. Same with lights and shadows etc. Isolate the problem or reduce the models and features. Again you can do this optimization and problem analysis on lights and shadows too.
I'm new to HTML5/Canvas/Game programming, but have been tinkering around with it after reading a couple of books. I THINK I have a fairly good idea of how things work out. This question asks several smaller questions, but in general is basically a "structural approach" question. I'm not expecting verbose responses, but hopefully small pointers here and there :) Here is a link to a non-scrolling, and currently rather boring Super Mario World.
Super Mario World Test
NOTE: Controls are Left/Right and Spacebar to jump. This is only setup for Firefox right now as I'm just learning.
Did I Do Something Wrong at This Point?
Currently I've just focused on how Mario runs and jumps, and think that I've gotten it down fairly okay. The coin box doesn't do anything and the background is just an image loaded in for looks. Here's my approach, please let me know if there is anything entirely wrong with this:
Allows Mario to jump by enacting on 2 Y velocities (Gravity and Jump variables)
Allows Mario to run by enacting on 1 velocity (Left or Right "Friction" + Acceleration)
Sprites are used and positioned according to keypress/keydown
I'm not sure if this is right, but I'm using a constructor function to build an object, then inside the main animation loop I'm calling the prototype.draw function for that object to update all variables and redraw the object.
I'm clearing the entire canvas each Frame
Should I be splitting this into more than just a draw function, like Mario.move()?
I've setup a GroundLevel and a JumpLevel variable to create 2 planes of gameplay. The JumpLevel is setup to allow for controlling how high Mario can jump on the fly. The 2 places would allow for the ground to rise like a hill - keeping the point at which Gravity overrules Mario's jumping force at the same distance from the ground.
For clarity sake, everything is separated into different JS files, but would obviously consolidate.
Moving Forward:
Now that I've finished setting up how Mario moves around (I think there are a couple other minor things I might do like mushroom up/down and shooting fireballs). I think I can figure that out, but I'm really lost when it comes to visualizing the following and how HTML5/Canvas can handle this easily:
Scrolling background (I've tried setting up Ground Tiles and using Screen Wrapping, but that seems to cause a lot of uneven issues since I was moving the tiles in the opposite direction. Unfortunately, since I'm trying to account for acceleration, this threw off the count and was causing gaps in the ground. I ditched this idea. Would a DIV beneath the canvas with a large background image be the best solution?
Enemies: Would I create enemies the same way and run a loop for collision detection on every enemy during each frame?
Background Boxes: I'm trying to allow Mario to stand on the boxes in the background, but am unsure how to approach this. I currently have boundaries setup for Mario to stay on the canvas, do I continue to expand these conditions to setup different boundaries based on the boxes? I can see that having several boxes on the screen and doing it this way would get kind of crazy, especially if I would be doing the same hit testing for enemies? I know I'm missing something here....
Level Movement: This is somewhat related. When the Right key is pressed, basically everything in the level needs to move to the left. Would I need to track out all positions of everything that could touch Mario (boxes for him to stand on and enemies for him to collide with) during every animation frame? This seems like it would get kind of inefficient?
Thanks to all! I'll keep this updated with results/solutions :)
Wow, okay. I really like your question because you've obviously done a lot of thinking on this, but partially because of that it's incredibly broad and conversational. You'd do better to find a forum to ask this question.
...That being said, I'm gonna answer the handful of points I'm qualified to, in no particular order. :)
Level Movement: That's a weird (read: inefficient) way to do it. I wouldn't do any calculations based on onscreen positions: track a canonical, camera-agnostic set of coordinates for everything in your level and update the visuals to match. This will stop you from running into weird niggling problems where framerate impacts what you can and can't walk through, or causing slower computers to let Mario run through enemies without being damaged sometimes. Tracking positions this way will incidentally fix a lot of your other problems.
You should absolutely be splitting this into multiple functions. Having movement code and rendering code in the same place is going to screw you, particularly by interacting malignantly with your update/refresh rate. It's going to essentially mean that every time the player does a tricky jump the game does more updates than usual which will make animation/hit detection/etc much less likely to be even.
Enemies: I'd suggest rolling this in with everything else. Do one hit-detection pass against everything, and if you hit something check to see what it was. You could try to optimize this by only checking any given entity against objects within 100 pixels of itself, but if you do it this way you'll need to run separate collision detection events for every enemy. Letting the enemies clip through each other would be computationally cheaper.
Edit: I'd like to clarify about my first point on 'level movement.' Essentially, what you don't want to do is move every entity onscreen every time the camera does, or to store all entity locations as offsets from the camera location (in which case you're still effectively having to move everything, every time the camera moves.)
Your ideal approach is to store your enemy, block, terrain locations with X/Y coordinates that are offset from the absolute top-left of the level (at the very beginning.) In order to render a frame, you'd do essentially this: (pseudocode because we're talking about a hypothetical level format!)
function GetVisible(x,width,level_entities_array) {
for (i = 0; i < count(level_array); i++){
if (level_entities_array[i][x] > x && level_entities_array[i][x] < x+width) {
visible_elements[] = level_entities_array[i][x];
}
}
return visible_elements;
}
Boom, you've got everything that should be inside the window. Now you subtract the camera's x offset from the entity's x location and ZAP, you've got its position on the canvas. Pose as a team, 'cause things just got real.
You'll note that I'm not bothering to cull on the Y axis. This can be rectified by extrapolation, which I'm guessing you can handle because you've made it this far. This will be necessary if you want to do any Mario-style vertical exploration.
Yes, I know my pseudocode looks like C# and JavaScript's unholy lovechild. I'm sorry, that's just how I roll at 11:30 at night. ;)
I want to create some randomly flying objects in a Unity 3D game. You can imagine them like fireflies. Now there're some tasks to do with them, include:
They usually fly randomly (of course).
They can fly away or fly back in some conditions.
I have to write some Javascript to do these things, but I don't know how to do. Can you help me? Thank you very much!
EDIT: I think I'll need these functions:
function Fly()
{
//control the gameObject to fly randomly
}
function FlyAway()
{
}
function FlyBack()
{
}
I would suggest that you look at the canvas tag, but then it will not work on IE as I don't know if 3D effects will work on excanvas well.
This gives you a drawable surface to do your graphics.
You will probably need to write your own primitive functions for the graphics, but it is very doable.
EDIT: You will need to use object oriented javascript for each of your fireflies, which will help you to move each of them each frame.
If you show your attempt at drawing graphics you can get more help.
As much as I hate condoning the use of Flash, this really sounds like a Flash job.
However, if you insist on using JavaScript, I'd thumb through some Chrome Experiments for 3D examples (w/canvas): http://www.chromeexperiments.com/
I've done an abstraction library that may help here:
DP_PanelManager
The library makes moving objects pretty simple - at the bottom of the page there's an example called "Useless Animation" - it's basically a checkerboard where each square randomly moves, changes size and changes opacity.
Something like that with fewer panels and a little math to do smoother travel (something like this should be easy enough to modify) should get you close.
The component also has simplified functions for collision detection and distance between panels (with bearing - the function will tell you how far apart two panels are AND in which direction they lay).
Hopes this gives you a headstart.
My approach would be
randomly create a x/y equation (may be from a given set, if you don't know how to 100% randomize this).
Decide, randomly if you go by the x or by the y.
decide the number of steps you take on the axis you chose in step 2.
move your element according to the x/y you get from the equation in step 1.
When you finished to move all the steps (number of steps is given in step 3), go back to step 1. In a loop.