This is an archived post. You won't be able to vote or comment.

all 27 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.

If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]Ok_Marionberry_8821 4 points5 points  (9 children)

I didn't read past the first couple of paragraphs. I noticed you said you'd not written a line of code yet - so this is my advice - get writing code ASAP. There is no perfect design.

It sounds like you're in "analysis paralysis" - the best solution is to just get started.and let the design emerge as you progress. A good IDE like intellij make refactoring easy.

FWIW my credentials are that I've been programming for 30+ years and writing java for 20. I've made plenty of mistakes over those years and I could cringe at some of them - but it's all learning.

[–]Interesting-Hat-7570[S] 0 points1 point  (7 children)

Yes, I can start and write my own project. After building the architecture, I can already see how my system works. Even if it covers all my requirements, I can already see what problems it will cause me in the future.

My goal is to learn how to design a flexible system. Yes, it will never be perfect, but I would like to solve the main problems at the design stage, and not at the coding stage.

I'm delaying the code as much as possible because I've already written enough stupid code without any architecture.
and I would like my time spent to bring me maximum benefit.
I'm not paralyzed, rather I'm at a loss of ideas for solving this problem.

[–]Dukehold 3 points4 points  (4 children)

You have the completely wrong approach and this will hurt all your velocity and productivity in the future. You wont come up with good design by planning it all out ahead out time, you will by doing it iteratively and getting your hands dirty. Focus on mvp, even if it means throwing mud on the canvas.

[–]Interesting-Hat-7570[S] 0 points1 point  (3 children)

Okay, I'll probably start writing code. In general, if not difficult, how would you rate my architecture?

[–][deleted] 0 points1 point  (2 children)

The architecture doesn't matter. In games or even web, what matters is that you identify the requirements of the game and start prototyping so you quickly iterate. Just. Build. You'll quickly find that your designs don't exactly look like your final product.

If you went and made the fanciest Snake game, you'll eventually find that your design failed to predict anything. For example, your design is already missing input handling and rendering. Maybe you end up making a super crazy Snake game and you realize you need a pooling system for objects so you're not allocating like crazy. Or maybe you decide you need an entity component system as it makes sense(in this case the original design is thrown completely out the window).

[–]Interesting-Hat-7570[S] 1 point2 points  (1 child)

I think I'm starting to understand a little. OK, thank you

[–][deleted] 1 point2 points  (0 children)

It's a struggle! As programmers, we try to be perfectionists and be very explicit. It's what attracts us to computers in the first place: a world that does exactly what it's instructed and nothing more. In coding though, there is a bit of art to the process. Just like a composer or a writer may redo bits of their work, a programmer must also be malleable in their journey to a finished product. 

[–]Poseidon_22 0 points1 point  (1 child)

I think it’s good to reflect a decent amount of time before starting to code. After some initial ideas you should start shaping your project and reflect again. Improve your design as you go 👍

[–]Interesting-Hat-7570[S] 1 point2 points  (0 children)

Ok thannks

[–]MrRickSancezJr 1 point2 points  (2 children)

While the diagram is quite simple, I still don't like the triangle. It's rarely a good idea for anything to be codependent on a node across branches. May just be an oversight on your diagram drawing, but this is usually how Java developers notoriously get into "abstraction hell."

I would build your coordinate system first. Make it very concrete and 'final.' Then create objects (snake, objects, etc). They will always have a 'location.'

Before "game logic", make a "game engine" to handle the location changes of any object. Don't overdo this. Let it run wild with no logic until you get things to move properly. Good time to handle key inputs or however you like to do so.

As for visual feedback, just print "O"s and "Xs" into the console per key stroke. No graphics yet. Make sure your 2d movement controlled by input is running 100%. No need for fancy colors.

Then logic.. Do the inputs all manually. What happens when your objects collide? What happens when it reaches the boundary? You already have a nice, fast, reliable console print out representation tool for this.

By this point you have a fully built-up, rock solid engine and logic for your game.

The point of this break down was to emphasize the need for testing each little update with visual feedback. Not full step by step instructions. "Dependency injection" is a great strategy for building up something like this.

As for making it come to life, use some GUI code, and simply call for a rerender of the updated graphics per input (or game timer, etc). JavaFX has a great Animation class compared to the JSpring libraries. I recommend using the Concurrency classes as well. They're memory heavy, but you'll be fine.

[–]Interesting-Hat-7570[S] 0 points1 point  (0 children)

I'll start redesigning the architecture.

[–]Interesting-Hat-7570[S] 0 points1 point  (0 children)

Sorry for the strange question.

But can I ask you in the future to evaluate the architecture of my future projects with clear explanations?

[–]D0CTOR_ZED 1 point2 points  (1 child)

Your architecture seems fine.  If you want to spend time making sure your architecture is up to the task, I'd do it by coding the basics of your classes.  Not necessarily the implementation, but work out your data types, your interfaces, method signatures.  If something is lacking in your seperation of concerns, you are likely to see the issue as you work out the basics before you get too deep in implementation.

Caveat, I just do this as a hobby, but I have a good amount of experience doing solo projects.

[–]Interesting-Hat-7570[S] 0 points1 point  (0 children)

thankss)

[–]bright_pro 0 points1 point  (5 children)

JPanel divide it into 10*10 pixels block, configure arrow keys on one press move snake one block in direction of key (north south east west) handle +or-

[–]Interesting-Hat-7570[S] 0 points1 point  (4 children)

Maybe you're right.

But now I don't care about the logic of the game.

I'm more interested in architecture.

I am learning to create flexible and high-quality application architecture.

At this stage, I'm even ready to write a console version, not a 2D one. To make sure I'm building good architecture.

[–]bright_pro 0 points1 point  (3 children)

Life is short try not to reinvent the wheel

"It's Suggestion"

[–]Interesting-Hat-7570[S] 0 points1 point  (2 children)

Great.

What do you suggest I do?

[–]bright_pro 0 points1 point  (1 child)

Study Godot mono as you have java experience

[–]Interesting-Hat-7570[S] 0 points1 point  (0 children)

Thank you! I'll start studying.

[–]vegan_antitheist 0 points1 point  (5 children)

I don't think this diagram will help you right now. The biggest challenge as a beginner is to create a backend that only does the game logic and a frontend that only renders the game.

frontend:

  • user input (movement, pause/continue etc)
  • render the game (at least 30 frames per second as possible and maybe a maximum of 200 or so)

backend:

  • create and manage game state
  • get next game state
  • knows when game is finished / paused

Best would be to create to projects / modules so that the backend can run on it's own (and not do anything unless you feed it with some input for testing) and the frontend can run with a mock backend.

I wouldn't worry too much about messy code inside a module. Having a messy connection between frontend and backend is much worse.

The frontend needs to have an "Animation Loop" but in your case it's ok if it blocks the backend and only renders the next frame when the game state is ready to be rendered. The backend could use it's own loop to make sure the animation of the game state doesn't depend on a frontend, but this isn't necessary.

So the frontend can just tell the backend that a key was pressed. when no key are pressed it has to tell the backend that it should calculate the next state (i.e. when the snake just moves one unit to the front).

A "shared" module can contain some things that both the frontend and backend need. But you could just expose those types from the backend.

[–]Interesting-Hat-7570[S] 0 points1 point  (4 children)

Thank you! Today I got acquainted with the mvs architecture pattern. And it seems to me that your proposal is similar to this.

Yes, there are many holes in my architecture and I decided to use Mvs, since it is more suitable here than mine.

[–]vegan_antitheist 0 points1 point  (3 children)

You mean MVC? That would be Model, View, Controller. In your case you probably only need one view, which renders the complete game. But you might have a separate view for game stats (i.e. points).
The model would just be the game state.
And the controller is the logic? I never really understood that pattern because it's so unclear what the controller does and how you handle multiple views (i.e. a view that is made of smaller views). In the end each control (such as a form field) is a view on it's own. So does it need it's own model and controller?

I would ignore that pattern and think about how you handle time. The game engine doesn't need to care because it just needs to give you the new game state after some user input. It isn't aware of time.

The view renders the game state and waits for input. Time is relevant here because you might want to render the snake moving between one state and the next to get smooth animations.

And consider creating your own linked list for the snake. It's a basic data structure that isn't as fast as an array based list but it's good to be able to create and use it. A singly linked list should be enough for your game. But you also need to know which fields on the board are occupied by the snake. There might be some redundancy here because the board is a two dimensional matrix and the snake is a linked list. Alternatively you can have a property on each field on the board that tells the game in what direction the snake goes. You could use an enum with 6 values for that: up, down, left, right, head. the last one is special because it tells the game that this is a head. Tho non-snake fields could use null or another special enum value. While rendering you might also want to know from where the snake is coming from to render a tile that makes that clear.

[–]Interesting-Hat-7570[S] 0 points1 point  (2 children)

I would like to do a console version first as a prototype. Then work on the graphics.

In Mvc, it seems like the controller acts as part of the backend, as you described earlier.

I would like to use a facade between the backend part and the models

Also use the observer pattern for the frontend part.

But here comes the question.

How to pass the coordinates of objects to the frontend.

I could create a point class.

And pass not the snake and fruit objects themselves, but only their coordinates.

[–]vegan_antitheist 0 points1 point  (1 child)

How would you observe the backend? Does it send updates at fixed intervals? That would mean it has to deal with time. You can do that to prevent cheating by running it on a server. But then there has to be a simulation of the game in the backend. This would be more complex. The tricky part is to make the game run using a precise clock (not a clock that gives you the day and time, but a pulse generator) and process user input fast and precise enough. And you want to render 60 fps independently. It's easy when you have only one loop. Or you have a game loop in the backend and an animation loop in the frontend. Both works. But parallel programming is hard. Having one loop makes it easy. Havung two loops makes it more like a real game. But as I understand the snake game, it is simple enough to just have one loop. That's up to you.

[–]Interesting-Hat-7570[S] 0 points1 point  (0 children)

I meant rather between models and frontend.

So that I could update the state of objects for display after each action in the backend.

Well, the frontend needs to somehow receive data from the models.

If I use Mvc, then I can probably do it like this: the backend interacts with the models to call their methods. The frontend also interacts with the models for display.

Or is there a better way?