Jump to content
  • Advertisement
    1. Past hour
    2. Hi, again i am at a point, were my incompetence makes me frustrated. I really try hard to solve my problems by myself before posting here. I have to mention that i have already worked with compute shader but until now i always read from one buffer and write to another. My kernel question: Is it possible in Directx11 SL 5.0 to bind a RWByteAddressBuffer to a computeshader as a UnorderdAccessView an then read a value from the buffer an write it back in the same dispatch ? This i exactly what i am doing. As a test i have also bound a StructuredBuffer to my computeShader as SRV with the same content as the RWByteAddressBuffer. When i read values from StructuredBuffer and write to RWByteAddressBuffer all works fine. => I conclude that the value is correctly read from StructuredBuffer and correctly written to the RWByteAddressBuffer Now comes the rediculous situation: If just read back the value from the same adress from the RWByteAddressBuffer and write it back the unchanged value to the same address in the RWByteAddressBuffer nothing is in the output and the model disappears. Many thanks in advance for everyone who can give me a hint. P.S. I know that i could work with two buffers, but because of the particle system (5 million) the buffers a very big and i would like to avoid this. The principle in most stages of the simulation will be, that the "old output buffer" is feeded as "input as input" buffer like a control loop. static const uint out_struc_stride = 32; // Size of RWByteBuffer_layout static const uint nThreads = 1000; // only as info, not used struct RWByteBuffer_layout { float4 Position ; float4 Color ; }; // structure buffer definition struct position_color_struc { float4 Position : POSITION; float4 Color : NORMAL; }; cbuffer CB_shared : register(b0) { uint nStructs; float time; } RWByteAddressBuffer out_data : register(u1); StructuredBuffer<position_color_struc> in_data : register(t25); [numthreads(nThreads, 1, 1)] void MoveParticles_ComputeShader(uint3 id : SV_DispatchThreadID) { uint range = nStructs / nThreads; position_color_struc input; for (uint i = id.x * range; i < (id.x + 1) * range; i++) { uint t = out_struc_stride * i; float4 in_position; float4 in_color ; bool do_read_from_byte_buffer = false; bool do_read_back = true; if (do_read_from_byte_buffer) { // read position, color from RWByteAddressBuffer ( does not work !!) in_position = out_data.Load4(t); in_color = out_data.Load4(t + 16); } else { // read position, color from StructuredBuffer ( does work ) input = in_data[i]; in_position = input.Position; in_color = input.Color; } out_data.Store4 (t, asuint(in_position)); out_data.Store4 (t + 16, asuint(in_color)); if (do_read_back) { // does NOT work even when reading first from structured Buffer // so we are shure that the value we read back from the structured buffer is OK // so reading from buffer and write back is IMPOSSIBLE ?? // read again from byte buffer in_position = out_data.Load4(t); // store bytebuffer out_data.Store4(t, asuint(in_position)); } } }
    3. Today
    4. MichaelAWolfe

      Need some ideas

      You could still have obstacles couldn't you (downed pillars, rocks, holes, etc.)? You did say you would see enemies wondering around the map as well correct?
    5. A name for the game has actually come up along those lines, but I'm supposed to keep it a secret. And I HAAAATE keeping secrets!!!
    6. So this is like a racing game on rails? I like irreversible's approach, slight possible tweaking: You could label each lane numbered, -1, 0, 1, 2 etc. Store the current lane position of the player as a float. Have a target lane number (as an integer) you are moving towards (could be the same as you are already in). Each iteration lerp the current lane towards the target lane (by a fixed amount if using fixed tick rate, or dT if using frame timing) On corners, preserve the lane information but because you are joining different 'segments' of track, do an additional lerp from one segment to another as you cross the corners. This way lane changing on corners 'just works'. If the difference between 2 players is less than some value (e.g. 0.5) they crash This might mean you can only turn e.g. left into a single side road from the left lane, which you may or may not want. You would also have to handle crashing on corners involving turning vehicles.
    7. Esteban5XG

      Project BlockchainZ [Available on itch.io]

      [BzPatch 2]: Updates and improvements! Hey everybody! New Patch is here! Say hello to Patch 1.0.2b (Patch notes below) A new update with nice improvements for a better game experience. Firstly we have reworked so hard the AI, so now they will react much better to the different situations, more work will be added, like advanced behaviors, different animations and there will be more in futures patches! Also we've done optimizations in the shooting feedback, first we add some shake to the camera. Also we have been working a lot in the IK stuff so when you shoot the gun move the character's arms and shoulders. And we have changed nearly all the SFXs for a more interesting version. Give it a try, you will notice with the first shoot. What is IK? IK is the acronym for Inverse Kinematics. IK is an animation technique that allows much more responsive animations in games. Unfortunatelly, this improvement forces us to turn off the option to disable the Right/Left Angle shooting until the next patch 😢 You'll see that now the difficulty level is a little bit more harder (We also took out rookie level), because we want the video game to be a really interesting challenge for every zombie killer. Nobody said that killing zombies was easy. The real challenge is to survive until your reinforcements arrive. Finally, and not less important, we have corrected some nasty bugs! Are you capable to save the bunker? Prove it and save the world: https://projectblockchainz.itch.io/projectbcz PSD.: we are still working on the story. And now we are so happy to show you some of the concept arts we have prepared. Check it! When we started developing the video game, we had the idea to create a huge city completely ruined by thousands of years of struggling. It would be a desolated scenario... More on the Devlog What do you think? Let us know on our Discord Server. Patch Notes: General improve on AI, now the bandits reacts much better. Big optimization in shooting feedback. Camera improvements. SFX improvements. IK optimizations. New SFX for each every weapon. Now the foots adjust to the terrain. The character reacts when is hitted. Fixed zombie speed bug. Not the zombies let some space after attacks. Rookie challenge level removed. Now the challenge level includes the difficulty. Challenge level adjustment in order to create a more interesting challenge for the player. Fixed some related bugs on AI. Aiming by the left is temporarily disabled while improving the character's IK. Now you can't train the last civilian in the bunker. Fixed the bug related to the updates, now it works fine. Some adjustment to max units at the same time, to avoid performance hitccups Minor Bugs Additionally, we are working on the auto-resolve feature that let the easy battles be done without wasting time Eg. when you have 20 soldiers and fight against 3 raiders. These kind of battles have no sense at this point, so we believe player doesn't need to waste time them. Just focus in the good ones. Once we have this feature totally balanced and tested, we'll update it in the next update! We really hope you enjoy these new improvements. If you find any bug, please tell us right here or through our Discord Server. Thanks a lot for all the support you are bringing to us. It's great to know how do you feel about Project BlockChainZ.
    8. Esteban5XG

      [Bz Patch 2]: How to kill a bug

      [BzPatch 2]: Updates and improvements! Hey everybody! New Patch is here! Say hello to Patch 1.0.2b (Patch notes below) A new update with nice improvements for a better game experience. Firstly we have reworked so hard the AI, so now they will react much better to the different situations, more work will be added, like advanced behaviors, different animations and there will be more in futures patches! Also we've done optimizations in the shooting feedback, first we add some shake to the camera. Also we have been working a lot in the IK stuff so when you shoot the gun move the character's arms and shoulders. And we have changed nearly all the SFXs for a more interesting version. Give it a try, you will notice with the first shoot. What is IK? IK is the acronym for Inverse Kinematics. IK is an animation technique that allows much more responsive animations in games. Unfortunatelly, this improvement forces us to turn off the option to disable the Right/Left Angle shooting until the next patch 😢 You'll see that now the difficulty level is a little bit more harder (We also took out rookie level), because we want the video game to be a really interesting challenge for every zombie killer. Nobody said that killing zombies was easy. The real challenge is to survive until your reinforcements arrive. Finally, and not less important, we have corrected some nasty bugs! Are you capable to save the bunker? Prove it and save the world: https://projectblockchainz.itch.io/projectbcz PSD.: we are still working on the story. And now we are so happy to show you some of the concept arts we have prepared. Check it! When we started developing the video game, we had the idea to create a huge city completely ruined by thousands of years of struggling. It would be a desolated scenario... More on the Devlog What do you think? Let us know on our Discord Server. Patch Notes: General improve on AI, now the bandits reacts much better. Big optimization in shooting feedback. Camera improvements. SFX improvements. IK optimizations. New SFX for each every weapon. Now the foots adjust to the terrain. The character reacts when is hitted. Fixed zombie speed bug. Not the zombies let some space after attacks. Rookie challenge level removed. Now the challenge level includes the difficulty. Challenge level adjustment in order to create a more interesting challenge for the player. Fixed some related bugs on AI. Aiming by the left is temporarily disabled while improving the character's IK. Now you can't train the last civilian in the bunker. Fixed the bug related to the updates, now it works fine. Some adjustment to max units at the same time, to avoid performance hitccups Minor Bugs Additionally, we are working on the auto-resolve feature that let the easy battles be done without wasting time Eg. when you have 20 soldiers and fight against 3 raiders. These kind of battles have no sense at this point, so we believe player doesn't need to waste time them. Just focus in the good ones. Once we have this feature totally balanced and tested, we'll update it in the next update! We really hope you enjoy these new improvements. If you find any bug, please tell us right here or through our Discord Server. Thanks a lot for all the support you are bringing to us. It's great to know how do you feel about Project BlockChainZ.
    9. Technically, if you change lane, you're moving (somewhat) diagonally, so your forward movement speed decreases. Likely you don't want to model that
    10. Hi everyone, I'm an orchestral music composer with 5 years experience. Now I would like to get experience in making music for games. I'm specialized in epic music and traditional big orchestrations, you can listen to some of my work on soundcloud/youtube at the bottom. Please contact me if you are interested, would love to hear from you. Best regards, Jonathan Soundtrack Portfolio: Rescored Trailers I did for practice:
    11. I started work on DiligentFX, a high-level renderer. As the first step, I reworked epipolar light scattering effect and made it ready-to-use component with a clear interface. Check it out on GitHub.
    12. jonri

      Islands and Land

      Yes, that is the ideal situation but it's not currently supported. There are some issue requests open for it, so hopefully it gets implemented eventually. My latest CPU numbers were just under 50% all-in, including the rest of the physics, rendering, etc. I'm not sure what I'm at for just my code. In that scene, 2 of the 3 boats were unoptimized, there are probably around 2000 potentially-buoyant faces in total, so a simpler hull should make a significant difference. I'm releasing what I have this week, and one of my goals for a future version will be to offer some options to trade accuracy for speed. I'll be sure to give it a go on mobile to see how things hold up. As you noted, this would prevent the inside of the boat from rendering. You need to sandwich the depth rendering of the closed hull between the rendering of the boat and the water. If you do find a better workaround, I'd love to know!
    13. lawnjelly

      Islands and Land

      Ahha! I have a solution, possibly. Draw the hulls first using colour without blending. This draws the colour and depth, no blending and is cheap. Draw a skybox over this, without using depth testing or depth write. This will draw the colour over the previous result. Now draw the boats. Now draw the ocean. I think this might work and would be super cheap. 🙂 /edit Ah darn this may interfere with the boat rendering. However you could use it to draw masked areas maybe, or get it to work with a cunning shader. I'm sure there must be a cheap solution! 🙂
    14. (note: there is ambiguity about where the line is drawn between raypunk - or raygun gothic - and atompunk as used in games like Fallout. I have attached a couple of images to illustrate the style I am talking about) Lately I have started browsing artwork and pictures of old science fiction movies from the 50's/60's again and started wondering - why isn't that aesthetic explored in videogames more frequently? It's a fresh and most of the times vibrant look at a future that never was, far away from the sleek designs of Mass Effect and the bleak colour palette of your average first person shooter. Let's face it, how many games can you name where the skies are a nice and warm yellow colour? Illustrators and film makers alike didn't care about realism and explored the realms of their imagination while throwing the laws of physics out of the window of their saucer shaped spaceships, and they gave us movies like This Island Earth or Forbidden Planet and the classic Star Trek series in return. So I have been trying to come up with a genre or game mechanic and I think a more campy and over-the-top version of something like Age Of Wonders would work great (yes, Planetfall might be set in a sci-fi setting but it's going in the complete opposite direction). Who wouldn't want to engage in diplomatic conversation with this friendly fellow while your fellow band of spacemen and -women fight off strange creatures with their trusty rayguns? What do you all think - is this a theme/idea worth exploring? What would make you want to play the 4X version of a 50's science fiction movie? Or would this lend itself better for a different genre instead?
    15. lawnjelly

      Islands and Land

      It might work but usually stuff like that is a big red flag to take care in case of pipeline stalls etc I think. It is all a roundabout way of trying to write to the depth buffer without writing out colour as I understand it? There may be a way of using alpha blending with transparent pixels, and getting the sorting / render order correct, maybe this will be faster. I think there is some support for changing the render order in Godot (I did it for my skybox) but I don't know if you can force this even with blending where things are often sorted back to front. Speaking for myself I'm also keen to have stuff that will work fast on mobile, so you have to be careful as things like that can kill the framerate for little visual gain. Also this is why my emphasis on shortcuts in the calculations, I saw from your latest version it was using 30-50% CPU. To give comparison, I think mine uses very low, figures around 0.1% CPU for 30 or so boats. However I think your approach could be optimized by using simplified hull (maybe a box or something) and lookup tables if you are feeling brave. I may get round to having a go at this when I eventually get home and can program again! :-)
    16. ArcanaDragon

      New Hero Added 02-19-2019

      New hero added: Haunted Nikes Click here to play Hero Land for free in your browser
    17. OK. That's a good focus. To get some ideas flowing, think of sayings or phrases other than the paper cuts thing. Like daily good deeds, or "paying it forward," or mountains from molehills.
    18. jonri

      Islands and Land

      Good point. I looked into it a little more and found it in the official documentation: http://docs.godotengine.org/en/3.0/tutorials/shading/screen-reading_shaders.html I think it should perform the same as any other screen-space post-processing shader (although I wonder if that means it would interfere with those as well), and it will only capture the screen texture once so having several boats using this at the same time won't decrease performance.
    19. We will see how to place OpenTK.GLControl on WPF window to make GUI application with 2D/3D graphics using modern OpenGL 3. This is the result VS project: EditedTriangle_WPFOpenGL31CSharp.zip How to create the project from scratch Note 1: RMB - Right Mouse Button click Note 2: Good Color calculator for normalized values: http://doc.instantreality.org/tools/color_calculator/ Create WPF application, with the name "EditedTriangle". See the screenshot: Download OpenTK.GLControl.zip and OpenTK.zip Create the empty "Libs" folder in the solution folder (where the ".sln" is placed) Unzip "OpenTK" and "OpenTK.GLControl" folder in the "Libs" folder Add references to "OpenTK.dll" and "OpenTK.GLControl.dll". For this: RMB on "References" -> select "Add Reference..." -> select "Browse" -> click the "Browse..." button -> select DLL's. See the screenshot with the result: Add "Assemblies". For this: select "Assemblies" -> "Framework" -> check: System.Drawing System.Windows.Forms WindowsFormsIntegration , see the screenshot with the result: Click "OK" button Open the file "MainWindow.xaml" in VS. Add this line as an attribute of the "Window" element: xmlns:opentk="clr-namespace:OpenTK;assembly=OpenTK.GLControl" Place this code inside of <Window></Window> element: <Grid> <DockPanel LastChildFill="True"> <StackPanel DockPanel.Dock="Right"> <Button x:Name="buttonSetBGColor" Content="Set BG Color" Margin="5" Click="buttonSetBGColor_Click"></Button> <Button x:Name="buttonSetTRColor" Content="Set TR Color" Margin="5" Click="buttonSetTRColor_Click"></Button> </StackPanel> <WindowsFormsHost Margin="5" Initialized="WindowsFormsHost_Initialized"> <opentk:GLControl x:Name="glControl" Load="glControl_Load" Paint="glControl_Paint" /> </WindowsFormsHost> </DockPanel> </Grid> Copy the code below to "MainWindow.xaml.cs" and run the project MainWindow.xaml.cs using System; using System.Windows; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics; namespace EditedTriangle { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private int _numOfVertices = 0; private int _uColorLocation; public MainWindow() { InitializeComponent(); } private void glControl_Load(object sender, EventArgs e) { glControl.MakeCurrent(); // Get a shader program ID int shaderProgram = InitShadersAndGetProgram(); _numOfVertices = InitVertexBuffers(); _uColorLocation = GL.GetUniformLocation(shaderProgram, "uColor"); if (_uColorLocation < 0) { MessageBox.Show("Failed to get uColorLocation variable"); return; } // Set a triangle color GL.Uniform3(_uColorLocation, 0.945f, 0.745f, 0.356f); // Set a color for clearing the glCotrol GL.ClearColor(new Color4(0.286f, 0.576f, 0.243f, 1f)); } private void glControl_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { GL.Viewport(0, 0, glControl.Width, glControl.Height); // Clear the glControl with set color GL.Clear(ClearBufferMask.ColorBufferBit); if (_numOfVertices != 0) { GL.DrawArrays(PrimitiveType.Triangles, 0, _numOfVertices); } // Swap the front and back buffers glControl.SwapBuffers(); } private int InitVertexBuffers() { float[] vertices = new float[] { 0.0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f }; int n = 3; int vbo; GL.GenBuffers(1, out vbo); // Get an array size in bytes GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); int sizeInBytes = vertices.Length * sizeof(float); // Send the vertex array to a video card memory GL.BufferData(BufferTarget.ArrayBuffer, sizeInBytes, vertices, BufferUsageHint.StaticDraw); // Config the aPosition variable GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0); GL.EnableVertexAttribArray(0); return n; } private int InitShadersAndGetProgram() { string vertexShaderSource = "#version 140\n" + "in vec2 aPosition;" + "void main()" + "{" + " gl_Position = vec4(aPosition, 1.0, 1.0);" + "}"; string fragmentShaderSource = "#version 140\n" + "out vec4 fragColor;" + "uniform vec3 uColor;" + "void main()" + "{" + " fragColor = vec4(uColor, 1.0);" + "}"; // Vertex Shader int vShader = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(vShader, vertexShaderSource); GL.CompileShader(vShader); // Check compilation string vShaderInfo = GL.GetShaderInfoLog(vShader); if (!vShaderInfo.StartsWith("No errors")) { MessageBox.Show(vShaderInfo); return -1; } // Fragment Shader int fShader = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(fShader, fragmentShaderSource); GL.CompileShader(fShader); string fShaderInfo = GL.GetShaderInfoLog(fShader); if (!fShaderInfo.StartsWith("No errors")) { MessageBox.Show(fShaderInfo); return -1; } int program = GL.CreateProgram(); GL.AttachShader(program, vShader); GL.AttachShader(program, fShader); GL.LinkProgram(program); GL.UseProgram(program); return program; } private void buttonSetBGColor_Click(object sender, RoutedEventArgs e) { var dialog = new System.Windows.Forms.ColorDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { GL.ClearColor(dialog.Color); glControl.Invalidate(); } } private void buttonSetTRColor_Click(object sender, RoutedEventArgs e) { var dialog = new System.Windows.Forms.ColorDialog(); if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { float r = dialog.Color.R / 255f; float g = dialog.Color.G / 255f; float b = dialog.Color.B / 255f; GL.Uniform3(_uColorLocation, r, g, b); glControl.Invalidate(); } } } } MainWindow.xaml <Window x:Class="EditedTriangle.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:EditedTriangle" xmlns:opentk="clr-namespace:OpenTK;assembly=OpenTK.GLControl" mc:Ignorable="d" Title="Triangle" Height="256" Width="290"> <Grid> <DockPanel LastChildFill="True"> <StackPanel DockPanel.Dock="Right"> <Button x:Name="buttonSetBGColor" Content="Set BG Color" Margin="5" Click="buttonSetBGColor_Click"></Button> <Button x:Name="buttonSetTRColor" Content="Set TR Color" Margin="5" Click="buttonSetTRColor_Click"></Button> </StackPanel> <WindowsFormsHost Margin="5"> <opentk:GLControl x:Name="glControl" Load="glControl_Load" Paint="glControl_Paint" /> </WindowsFormsHost> </DockPanel> </Grid> </Window>
    20. fleabay

      Assets used for free game?

      It would likely be a win in court regardless. Trademarks don't prevent all use, just certain specific uses. Trouble is, nobody wants to be the one to set precedence in court, including Turbosquid, who settled out of court recently with BMW for selling car models with the logo. (I think it was BMW) Anyway, it's a touchy subject because people think trademarks are all powerful because of the status quo and can't reason about it objectively with legal jargon. It's like telling someone that cholesterol isn't bad for you after all the years of being told that cholesterol = bad!
    21. SmaugA

      Mobile V0.1.6 Update

      ENG: This update introduces many changes: Added new user interface changes; Added game menu; Added store for starting bonuses; Added store at the end of levels; Added save system; Improved and fixed camera behavior; Added some little changes. In the store of starting bonuses purchase is due to the accumulated score points. Improving your level with score points, you will open new additional bonuses for improvement. Maximum game level is 10 now. In the store at the end of the levels, you can replenish your stocks of ammo and health. RUS: Это обновление вносит много изменений: Дополнен интерфейс пользователя; Добавлено меню игры; Добавлен магазин для стартовых бонусов; Добавлен магазин в конце уровней; Добавлена система сохранений; Улучшено и исправлено поведение камеры; Добавлены мелкие исправления. В магазине стартовых бонусов покупка осуществляется за счет накопленных очков мощи. Улучшая свой уровень за очки мощи , Вам будут открываться дополнительные бонусы для улучшения. Всего в игре 10 уровне на данный момент. В магазине в конце уровней можно пополнить свои запасы патронов и здоровья. You can download apk file here: https://drive.google.com/file/d/16pae6KTY9XHbB8cSws600jLnH31eVxxH/view?usp=sharing
    22. MiniDarkOF

      Any tips for Better Writing?

      really thanks guys!
    23. duke_meister

      Bit of a cleanup

      using System; using System.Drawing; using System.Linq; using System.Windows.Forms; namespace GdiSnake { public sealed partial class Form1 : Form { // our unchanging values: // playfield height & width const int PlayfieldWidth = 80; const int PlayfieldHeight = 40; const int CellSize = 9; const int PlayfieldYOffset = 50; const int PlayfieldXOffset = 20; Color[] CellColors = { Color.White, Color.Blue, Color.CornflowerBlue, Color.Coral, Color.Black }; // timeout to adjust speed of snake const int MillisecondsTimeout = 40; // our playfield; stores FieldVals instead of ints so we don't have to remember them readonly FieldVals[,] PlayField = new FieldVals[PlayfieldWidth, PlayfieldHeight]; // not yet used until we increase length of snake int _snakeBodyLen; // not including head // which direction (SnakdDirs enum) the snake is currently moving SnakeDirs _snakeDir; // position of the one-and-only piece of food; use our own coordinate class, Pos readonly Pos FoodPos = new Pos(0, 0); // defines the snake; each element tells us which coordinates each snake piece is at static int _maxSnakeLen = 31; readonly Pos[] _snakeCells = new Pos[_maxSnakeLen]; // guess int _score = 0; // for randomizing things like food placement Random _rnd; // how many body pieces the snake will increase by when it eats food int SnakeSizeIncrease = 2; // could've used something existing, but made a simple screen coordinate class public class Pos { public int X { get; set; } public int Y { get; set; } public Pos(int x, int y) { X = x; Y = y; } } // these make it easy (for the human) to know what each cell contains public enum FieldVals { Empty, SnakeHead, SnakeBody, SnakeFood, Border } // these make it easy (for the human) to read snake the direction public enum SnakeDirs { Up, Right, Down, Left } public Form1() { DoubleBuffered = true; InitializeComponent(); RunGame(); } public void Timer1_Tick(object sender, EventArgs e) { CheckForKeyboardCommand(); CheckForSnakeOutOfBounds(); CheckForSnakeCollisionWithSelf(); UpdateSnakeBodyPosition(); CheckSnakeHasEatenFood(); Invalidate(); } public void CheckForSnakeCollisionWithSelf() { if (_snakeCells.Skip(1).Any(pos => pos.X == _snakeCells.First().X && pos.Y == _snakeCells.First().Y)) { EndGame(false); } } /// <summary> /// Work out the initial coordinates of the snake's body parts /// </summary> public void SetUpSnake() { _snakeBodyLen = 4; // create the empty snake array cells for (var i = 0; i < _snakeCells.Length; i++) { _snakeCells[i] = new Pos(0, 0); } // randomly choose snake's initial direction _snakeDir = (SnakeDirs)_rnd.Next((int)SnakeDirs.Up, (int)SnakeDirs.Left + 1); // First set the position of the snake's head. // We'll work out the rest of the snake body coords based on which // direction it's initially facing. _snakeCells.First().X = PlayfieldWidth / 2; _snakeCells.First().Y = PlayfieldHeight / 2; switch (_snakeDir) { case SnakeDirs.Up: // make the snake's body go below the head, as it's moving up for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X; _snakeCells[i].Y = _snakeCells[i - 1].Y + 1; } break; case SnakeDirs.Right: // make the snake's body go left of the head, as it's moving right for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X - 1; _snakeCells[i].Y = _snakeCells.First().Y; } break; case SnakeDirs.Down: // make the snake's body go above of the head, as it's moving down for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X; _snakeCells[i].Y = _snakeCells[i - 1].Y - 1; } break; case SnakeDirs.Left: // make the snake's body go right of the head, as it's moving left for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X + 1; _snakeCells[i].Y = _snakeCells.First().Y; } break; } } /// <summary> /// Check the keyboard for arrow keys /// I got the code off the net (see bottom of code); no point re-creating this /// </summary> public void CheckForKeyboardCommand() { if (NativeKeyboard.IsKeyDown(KeyCode.Down)) // player hit Down arrow { // can't hit down while going up; game over if (_snakeDir == SnakeDirs.Up) EndGame(false); // change snake direction to down _snakeDir = SnakeDirs.Down; } else if (NativeKeyboard.IsKeyDown(KeyCode.Up)) { // can't hit up while going down; game over if (_snakeDir == SnakeDirs.Down) EndGame(false); // change snake direction to up _snakeDir = SnakeDirs.Up; } else if (NativeKeyboard.IsKeyDown(KeyCode.Left)) { // can't hit left while going right; game over if (_snakeDir == SnakeDirs.Right) EndGame(false); // change snake direction to left _snakeDir = SnakeDirs.Left; } else if (NativeKeyboard.IsKeyDown(KeyCode.Right)) { // can't hit right while going left; game over if (_snakeDir == SnakeDirs.Left) EndGame(false); // change snake direction to right _snakeDir = SnakeDirs.Right; } } /// <summary> /// See if snake has eaten the food /// </summary> public void CheckSnakeHasEatenFood() { // if snake head is in the same x,y position as the food // NB: First() is a Linq function; it gives me the first element in the array if (_snakeCells.First().X == FoodPos.X && _snakeCells.First().Y == FoodPos.Y) { IncrementScore(); MakeNewFood(); IncreaseSnakeSize(); } } public void IncreaseSnakeSize() { if (_snakeBodyLen + SnakeSizeIncrease < _maxSnakeLen) { _snakeBodyLen += SnakeSizeIncrease; } } public void DrawScore(Graphics g) { WriteAt(g, $"Score: {_score} Snake Size: {_snakeBodyLen}", 0, 0); } public void IncrementScore() { ++_score; } /// <summary> /// Put food item at random location /// </summary> public void MakeNewFood() { int x, y; do { // this ensures we're not putting the food on top of the snake, or the border x = _rnd.Next(1, PlayfieldWidth - 1); y = _rnd.Next(1, PlayfieldHeight - 1); } while (_snakeCells.Any(pos => pos.X == x || pos.Y == y)); // set the food coords FoodPos.X = x; FoodPos.Y = y; // update the playfield position with the food value PlayField[FoodPos.X, FoodPos.Y] = FieldVals.SnakeFood; } void CheckForSnakeOutOfBounds() { // snake mustn't be on any border cell, or game over if (_snakeCells.First().Y < 1 || _snakeCells.First().X > PlayfieldWidth - 2 || _snakeCells.First().Y > PlayfieldHeight - 2 || _snakeCells.First().X < 1) { EndGame(false); } } /// <summary> /// Move the snake pieces appropriately. I just did the simplest thing that I thought of. /// </summary> void UpdateSnakeBodyPosition() { // Last piece of snake's tail will always become empty as the snake moves // NB: Last() is a Linq function; it gives me the last element in the array (end of snake tail) PlayField[_snakeCells[_snakeBodyLen].X, _snakeCells[_snakeBodyLen].Y] = FieldVals.Empty; // move the 'middle' section of the snake one cell along for (int i = _snakeCells.Length - 1; i > 0; i--) { _snakeCells[i].X = _snakeCells[i - 1].X; _snakeCells[i].Y = _snakeCells[i - 1].Y; } // move the snake's head, depending on direction moving // the body was already moved above switch (_snakeDir) { case SnakeDirs.Up: // moved the snake head up 1 (-ve Y direction) --_snakeCells.First().Y; break; case SnakeDirs.Right: // moved the snake head right 1 (+ve X direction) ++_snakeCells.First().X; break; case SnakeDirs.Down: // moved the snake head up 1 (+ve Y direction) ++_snakeCells.First().Y; break; case SnakeDirs.Left: // moved the snake head left 1 (-ve X direction) --_snakeCells.First().X; break; } // Set the playfield position at the head of the snake, to be... the snake head! PlayField[_snakeCells.First().X, _snakeCells.First().Y] = FieldVals.SnakeHead; // Set the positions on the playfield for the snake body cells // so we know to draw them // NB: Skip(1).Take(4) is Linq; it gives me the array left after // skipping the first item, then grabbing the next 4 (so in this // case misses the first and last). foreach (var cell in _snakeCells.Skip(1).Take(4)) { PlayField[cell.X, cell.Y] = FieldVals.SnakeBody; } } /// <summary> /// Just show a message and exit (can only lose right now) /// </summary> /// <param name="win"></param> void EndGame(bool win) { //var g = CreateGraphics(); //WriteAt(g, $"YOU DIED. Score: {_score} Snake Length: {_snakeBodyLen}", 0, 20); RunGame(); } public void RunGame() { _rnd = new Random(); _score = 0; for (var i = 0; i < PlayfieldWidth; i++) { for (var j = 0; j < PlayfieldHeight; j++) { PlayField[i, j] = FieldVals.Empty; } } // create the initial snake cell coords (place it on playfield) SetUpSnake(); // start with an initial piece of food MakeNewFood(); timer1.Interval = MillisecondsTimeout; timer1.Start(); } /// <summary> /// Set the console size appropriately & draw the border, leaving room for the score /// </summary> void DrawBorder( Graphics g) { for (var i = 0; i < PlayfieldWidth; i++) { DrawCell(g, FieldVals.Border, i, 0); DrawCell(g, FieldVals.Border, i, PlayfieldHeight); } for (var i = 0; i < PlayfieldHeight; i++) { DrawCell(g, FieldVals.Border, 0, i); DrawCell(g, FieldVals.Border, PlayfieldWidth - 1, i); } } /// <summary> /// Go through every element of the 2d array, only drawing a cell /// if it has a value (other than 0). This way we only draw the /// cells that need to be updated. A bit like Invalidate() in GDO. /// Pretty self-explanatory; if a cell has a value, draw the character /// appropriate for it. The space is only used to overwrite the last /// piece of the snake's tail. /// </summary> void UpdatePlayfield( Graphics g) { DrawBorder( g); for (var i = 1; i < PlayfieldWidth - 1; i++) { for (var j = 1; j < PlayfieldHeight - 1; j++) { switch (PlayField[i, j]) { case FieldVals.SnakeHead: DrawCell( g, FieldVals.SnakeHead, i, j + 1); break; case FieldVals.SnakeBody: DrawCell(g, FieldVals.SnakeBody, i, j + 1); break; case FieldVals.SnakeFood: DrawCell(g, FieldVals.SnakeFood, i, j + 1); break; } } } } public void DrawCell( Graphics g ,FieldVals cellType, int x, int y) { if (cellType != FieldVals.Empty) { Color color = CellColors[(int)cellType]; g.FillRectangle(new SolidBrush(color), x * CellSize + PlayfieldXOffset, y * CellSize + PlayfieldYOffset, CellSize, CellSize); } } private void WriteAt( Graphics g, string s, int x, int y) { using (var drawFont = new Font("Arial", 16)) using (var drawBrush = new SolidBrush(System.Drawing.Color.Black)) { g.DrawString(s, drawFont, drawBrush, x, y); } } private void Form1_Paint(object sender, PaintEventArgs e) { UpdatePlayfield( e.Graphics); DrawScore( e.Graphics); } } /// <summary> /// Codes representing keyboard keys. /// </summary> /// <remarks> /// Key code documentation: /// http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx /// </remarks> internal enum KeyCode { Left = 0x25, Up, Right, Down } /// <summary> /// Provides keyboard access. /// </summary> internal static class NativeKeyboard { /// <summary> /// A positional bit flag indicating the part of a key state denoting /// key pressed. /// </summary> const int KeyPressed = 0x8000; /// <summary> /// Returns a value indicating if a given key is pressed. /// </summary> /// <param name="key">The key to check.</param> /// <returns> /// <c>true</c> if the key is pressed, otherwise <c>false</c>. /// </returns> public static bool IsKeyDown(KeyCode key) { return (GetKeyState((int)key) & KeyPressed) != 0; } /// <summary> /// Gets the key state of a key. /// </summary> /// <param name="key">Virtual-key code for key.</param> /// <returns>The state of the key.</returns> [System.Runtime.InteropServices.DllImport("user32.dll")] static extern short GetKeyState(int key); } }
    24. Brain

      Assets used for free game?

      If in doubt, use a large site like turbosquid, and pay something for the models. They have some very expensive models on there, but also some very good ones for pocket change. Most of my 3D models in my game come from there and/or are kitbashes of stuff on there. Because you've paid them, and they've certified and guaranteed that the license is correct, so long as you abide by the reasonable terms (e.g. don't go using a porsche in your racing game or an AK-47 in your first person shooter!) if someone did try to sue you, you have reasonable defence that you bought it from turbosquid, and paid for it, and turbosquid have done their due diligence, which pins the fault clearly on the asset's seller. It's not completely watertight and I am no lawyer, but this is how i see it, and it's common sense to me. I'm sure if someone was vindictive enough, they could go after you, turbosquid, and the seller of the asset together. If in doubt, take legal advice, if still in doubt don't do it!
    25. Brain

      Mr Boom's Firework Factory

      Mr Boom's Firework Factory is a fast paced puzzle game written in Unreal Engine 4 with a combination of Blueprints and C++. Through many levels of mayhem, you'll discover the secret behind the firework factory. This game is approaching the point where a complete vertical slice can be submitted to various distributors such as steam. I welcome contributors, please note that this is a hobby project and there is at yet no agreement as to profit sharing etc.
    26. Brain

      Firework Factory 3D version

      Mr Boom's Firework Factory rewrite in Unreal Engine 4. Previously attempted rewrite from scratch using DirectX 11. Due for release July 2019.
    27. Trying to promote a game, engine, library, etc.? We have the Projects section, and the Your Announcements forum. You could also consider posting blogs, but keep in mind that people generally react poorly to blogs that are just an ad, and prefer to see project updates, behind-the-scenes info, "how to" guides, post mortems, etc. We also have a gallery section. If you're a contractor/freelancer wanting to advertise your services, check out the contractors section.
    28. Rutin

      Psy - Dungeon Challenge

      I hit every key until I could heal.
    29. r1ckparker

      Psy - Dungeon Challenge

      Thanks for the kind comments everyone, I enjoyed this challenge. Looking forward to the next one! Oops I forgot to add that key press to the Instructions screen! Pressing H uses a health potion. Thanks!
    30. Hi, We just about finished our open-source video game. Game uses the Defold cross-platform game engine. You can see this game at below URL link: http://fallenangelsoftware.com/Maxima_3-5_Engine.html Enjoy! Jesse
    31. Take a look at the Your Announcements forum.
    32. 8Observer8

      c# console snake game

      I have a step-by-step instruction how to make a prototype of 2D Snake Game using GDI. @phil67rpg may be you will read my instruction? @phil67rpg it is simple to convert it from GDI to WPF or to OpenGL or even to 3D with OpenGL. I wrote instruction how to convert form GDI to OpenGL 3: https://www.gamedev.net/blogs/entry/2266689-101-snake-winforms-opengl-31/
    33. duke_meister

      c# console snake game

      Not true. For instance in my version it represents a cell, not a pixel/point. ed: I could still have used it of course, but I prefer the abstraction.
    34. Hi, I am new here. I have a question. Can I share my Promotional posts.
    35. Thanks for the insight! This seems like a solid plan as I would have to define the lanes eventually anyway. In this case the object should only lerp over either the x- or z-axis, depending on which direction the lane goes (or maybe this is not necessary if I keep the transformations local?). When the player is on an intersection (inside the red box in the picture), instead of changing lanes the player turns left or right on the road. Currently not in a position to try this approach but assuming the player has a constant forward movement, adding a lerp over a single axis won't interfere?
    36. Rutin

      Assets used for free game?

      It amazes me how much is stolen on sites that sell 3D models... Thankfully I don't buy assets from such hubs, only through channels I know and trust if I don't do it in house or myself personally.
    37. lawnjelly

      Assets used for free game?

      And be aware that a lot of assets marked as 'personal use' are stolen assets, that the uploader has no rights to distribute. (The implication being that if you are just using them personally and not distributing, the original owners won't find out)
    38. Webellion

      Five Nations

      Five Nations is a real-time sci-fi strategy game for PC platforms, Switch, and mobile. Encompassing tactical combat in space in real-time mixed with micromanagement of economy, construction, and production, it will play both in single player and multiplayer modes. The RTS mechanics being custom-made to deliver action-packed gameplay. Gameplay You are a commander of one of the five greatest galactic empires in the far future Develop your space facilities, mining stations, factories, power plants, and research centers. Produce a gigantic armada of spacecraft to confront and destroy your rivals by applying shrewd strategies to outmaneuver their fleets. All this in real-time, by micromanaging your spaceships and structures through conventional RTS mechanics tailored to modern action-packed gameplay. Story In the near future, countries of the Earth are clustered in an international organization to create co-operation between states and prevent future wars. Aligning mankind under a common flag helped the economic and technological progress that paved the way for space conquest. During the colonization of the solar system, a group of pioneers discovered a wormhole that led to an unknown corner of the galaxy. Although the first attempt to enter the wormhole was deemed a complete success, the second expedition never returned... Join our Discord server and get Super Early Access https://discord.gg/uSSzUKs Social Media Facebook fan page: https://www.facebook.com/fivenationsthegame Instagram: https://instagram.com/fivenationsthegame GameJolt: https://gamejolt.com/games/fivenations/389358 Itch.io: https://webellionlimited.itch.io/five-nations Twitter: https://twitter.com/webellion
    39. duke_meister

      c# console snake game

      I just converted my console snake code to GDI. Just to show how a good design can be easily used with any underlying drawing method. So really, discussion about which is 'harder' is moot. Phil, happy to take you through the design process step by step if you like.
    40. duke_meister

      Changes I made...

      So essentially the changes I made are: Create a WinForms app instead of Console (obviously) Move my game loop code from a for loop to a timer Tick Move UpdatePlayfield() into the form Paint() Change WriteAt (which wrote on the console) to DrawCell (to draw on the form) That's pretty much it! Apart from some minor stuff which I'll go into next post. Some of the code can still be removed, e.g. there's no need to 'erase' the last snake tail piece as in the console version, and we could use different keyboard technique, but it works BTW I'm not saying this is a great design, it's quick and dirty to be honest, which was the original intention (to get it done fast, but not throwing good design right out the window..)
    41. 8Observer8

      c# console snake game

      I think @phil67rpg wants to create a list of foods in random position. Or maybe I understand wrong. Okay, lets generate one food after eating. You can replace it with one line of code with built in class Point: Point foodPos = new Point(0, 0); @phil67rpg what do you want to add in your code next? using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace SnakeByPhil_WinFormsGDI { public partial class Form1 : Form { public Form1() { InitializeComponent(); CenterToScreen(); timer1.Interval = 200; timer2.Interval = 500; timer2.Start(); } int x = 0, y = 0; Random rnd = new Random(); int move = 1; Point foodPos = new Point(0, 0); private void timer2_Tick(object sender, EventArgs e) { move = rnd.Next(1, 5); foodPos.X = rnd.Next(0, 290); foodPos.Y = rnd.Next(0, 290); } private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = this.CreateGraphics(); DrawRectangle(g, 340 + x, 280 + y, Color.Green); DrawRectangle(g, 330 + x, 280 + y, Color.Black); //DrawRectangle(g, 150 + x, 150 + y, Color.Green); //DrawRectangle(g, 140 + x, 150 + y, Color.Black); DrawRectangle(g, foodPos.X, foodPos.Y, Color.Red); g.Dispose(); } private void DrawRectangle(Graphics g, int x, int y, Color color) { SolidBrush brush = new SolidBrush(color); Rectangle rect = new Rectangle(x, y, 10, 10); g.FillRectangle(brush, rect); brush.Dispose(); } private void timer1_Tick(object sender, EventArgs e) { switch (move) { case 1: for (int i = 0; i <= 20; i++) { x++; } break; case 2: for (int i = 0; i <= 20; i++) { x--; } break; case 3: for (int i = 0; i <= 20; i++) { y++; } break; case 4: for (int i = 0; i <= 20; i++) { y--; } break; } if (MouseButtons == MouseButtons.Left) { } Invalidate(); } } }
    42. duke_meister

      All done

      using System; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace GdiSnake { public sealed partial class Form1 : Form { // our unchanging values: // playfield height & width const int PlayfieldWidth = 80; const int PlayfieldHeight = 40; const int CellSize = 9; const int PlayfieldYOffset = 50; const int PlayfieldXOffset = 20; // game pieces // no longer required //const string EmptyCell = " "; //const string SnakeHeadCell = "@"; //const string SnakeBodyCell = "o"; //const string FoodCell = "."; // timeout to adjust speed of snake const int MillisecondsTimeout = 30; // our playfield; stores FieldVals instead of ints so we don't have to remember them readonly FieldVals[,] PlayField = new FieldVals[PlayfieldWidth, PlayfieldHeight]; // not yet used until we increase length of snake int _snakeBodyLen; // not including head // which direction (SnakdDirs enum) the snake is currently moving SnakeDirs _snakeDir; // position of the one-and-only piece of food; use our own coordinate class, Pos readonly Pos FoodPos = new Pos(0, 0); readonly Pos EraserPos = new Pos(0, 0); // defines the snake; each element tells us which coordinates each snake piece is at static int _maxSnakeLen = 31; Pos[] _snakeCells = new Pos[_maxSnakeLen]; // guess int _score = 0; // for randomizing things like food placement Random _rnd; // how many body pieces the snake will increase by when it eats food int SnakeSizeIncrease = 2; // could've used something existing, but made a simple screen coordinate class public class Pos { public int X { get; set; } public int Y { get; set; } public Pos(int x, int y) { X = x; Y = y; } } // these make it easy (for the human) to know what each cell contains public enum FieldVals { DontDraw, Empty, SnakeHead, SnakeBody, SnakeFood, Border } // these make it easy (for the human) to read snake the direction public enum SnakeDirs { Up, Right, Down, Left } public Form1() { DoubleBuffered = true; InitializeComponent(); RunGame(); } public void Timer1_Tick(object sender, EventArgs e) { CheckForKeyboardCommand(); // using a timer now //AdjustGameSpeed(); // done in paint() now //UpdatePlayfield(); CheckForSnakeOutOfBounds(); CheckForSnakeCollisionWithSelf(); UpdateSnakeBodyPosition(); CheckSnakeHasEatenFood(); Invalidate(); } public void CheckForSnakeCollisionWithSelf() { if (_snakeCells.Skip(1).Any(pos => pos.X == _snakeCells.First().X && pos.Y == _snakeCells.First().Y)) { EndGame(false); } } /// <summary> /// Work out the initial coordinates of the snake's body parts /// </summary> public void SetUpSnake() { _snakeBodyLen = 4; // create the empty snake array cells for (var i = 0; i < _snakeCells.Length; i++) { _snakeCells[i] = new Pos(0, 0); } // randomly choose snake's initial direction _snakeDir = (SnakeDirs)_rnd.Next((int)SnakeDirs.Up, (int)SnakeDirs.Left + 1); // have simplified the snake placement //int[] xOffsets = { 0, _snakeBodyLen * -1, 0, _snakeBodyLen }; //int[] yOffsets = { _snakeBodyLen, 0, _snakeBodyLen * -1, 0 }; //int xOffset = xOffsets[(int)_snakeDir]; //int yOffset = yOffsets[(int)_snakeDir]; // First set the position of the snake's head. // We'll work out the rest of the snake body coords based on which // direction it's initially facing. _snakeCells.First().X = PlayfieldWidth / 2; _snakeCells.First().Y = PlayfieldHeight / 2; switch (_snakeDir) { case SnakeDirs.Up: // make the snake's body go below the head, as it's moving up for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X; _snakeCells[i].Y = _snakeCells[i - 1].Y + 1; } break; case SnakeDirs.Right: // make the snake's body go left of the head, as it's moving right for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X - 1; _snakeCells[i].Y = _snakeCells.First().Y; } break; case SnakeDirs.Down: // make the snake's body go above of the head, as it's moving down for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X; _snakeCells[i].Y = _snakeCells[i - 1].Y - 1; } break; case SnakeDirs.Left: // make the snake's body go right of the head, as it's moving left for (int i = 1; i < _snakeBodyLen; i++) { _snakeCells[i].X = _snakeCells.First().X + 1; _snakeCells[i].Y = _snakeCells.First().Y; } break; } } // not required for GDI version //public void AdjustGameSpeed() //{ // // delay so the game isn't too fast. Halve the delay (to go faster) when going left or right // // as it appears that going up/down is faster // Task.Delay(_snakeDir == SnakeDirs.Up || _snakeDir == SnakeDirs.Right ? MillisecondsTimeout / 2 : MillisecondsTimeout).Wait(); //} /// <summary> /// Check the keyboard for arrow keys /// I got the code off the net (see bottom of code); no point re-creating this /// </summary> public void CheckForKeyboardCommand() { if (NativeKeyboard.IsKeyDown(KeyCode.Down)) // player hit Down arrow { // can't hit down while going up; game over if (_snakeDir == SnakeDirs.Up) EndGame(false); // change snake direction to down _snakeDir = SnakeDirs.Down; } else if (NativeKeyboard.IsKeyDown(KeyCode.Up)) { // can't hit up while going down; game over if (_snakeDir == SnakeDirs.Down) EndGame(false); // change snake direction to up _snakeDir = SnakeDirs.Up; } else if (NativeKeyboard.IsKeyDown(KeyCode.Left)) { // can't hit left while going right; game over if (_snakeDir == SnakeDirs.Right) EndGame(false); // change snake direction to left _snakeDir = SnakeDirs.Left; } else if (NativeKeyboard.IsKeyDown(KeyCode.Right)) { // can't hit right while going left; game over if (_snakeDir == SnakeDirs.Left) EndGame(false); // change snake direction to right _snakeDir = SnakeDirs.Right; } } /// <summary> /// See if snake has eaten the food /// </summary> public void CheckSnakeHasEatenFood() { // if snake head is in the same x,y position as the food // NB: First() is a Linq function; it gives me the first element in the array if (_snakeCells.First().X == FoodPos.X && _snakeCells.First().Y == FoodPos.Y) { IncrementScore(); MakeNewFood(); IncreaseSnakeSize(); } } public void IncreaseSnakeSize() { if (_snakeBodyLen + SnakeSizeIncrease < _maxSnakeLen) { _snakeBodyLen += SnakeSizeIncrease; } } public void DrawScore(Graphics g) { WriteAt(g, $"Score: {_score} Snake Size: {_snakeBodyLen}", 0, 0); } public void IncrementScore() { ++_score; } /// <summary> /// Put food item at random location /// </summary> public void MakeNewFood() { int x, y; do { // this ensures we're not putting the food on top of the snake, or the border x = _rnd.Next(1, PlayfieldWidth - 1); y = _rnd.Next(1, PlayfieldHeight - 1); } while (_snakeCells.Any(pos => pos.X == x || pos.Y == y)); // set the food coords FoodPos.X = x; FoodPos.Y = y; // update the playfield position with the food value PlayField[FoodPos.X, FoodPos.Y] = FieldVals.SnakeFood; } void CheckForSnakeOutOfBounds() { // snake mustn't be on any border cell, or game over if (_snakeCells.First().Y < 1 || _snakeCells.First().X > PlayfieldWidth - 2 || _snakeCells.First().Y > PlayfieldHeight - 2 || _snakeCells.First().X < 1) { EndGame(false); } } /// <summary> /// Move the snake pieces appropriately. I just did the simplest thing that I thought of. /// </summary> void UpdateSnakeBodyPosition() { // remember the position of the snake's last piece so that later, // after drawing the snake, we can set it to the 'don't draw' value EraserPos.X = _snakeCells[_snakeBodyLen].X; EraserPos.Y = _snakeCells[_snakeBodyLen].Y; // Last piece of snake's tail will always become empty as the snake moves // NB: Last() is a Linq function; it gives me the last element in the array (end of snake tail) PlayField[_snakeCells[_snakeBodyLen].X, _snakeCells[_snakeBodyLen].Y] = FieldVals.Empty; // move the 'middle' section of the snake one cell along for (int i = _snakeCells.Length - 1; i > 0; i--) { _snakeCells[i].X = _snakeCells[i - 1].X; _snakeCells[i].Y = _snakeCells[i - 1].Y; } // move the snake's head, depending on direction moving // the body was already moved above switch (_snakeDir) { case SnakeDirs.Up: // moved the snake head up 1 (-ve Y direction) --_snakeCells.First().Y; break; case SnakeDirs.Right: // moved the snake head right 1 (+ve X direction) ++_snakeCells.First().X; break; case SnakeDirs.Down: // moved the snake head up 1 (+ve Y direction) ++_snakeCells.First().Y; break; case SnakeDirs.Left: // moved the snake head left 1 (-ve X direction) --_snakeCells.First().X; break; } // Set the playfield position at the head of the snake, to be... the snake head! PlayField[_snakeCells.First().X, _snakeCells.First().Y] = FieldVals.SnakeHead; // Set the positions on the playfield for the snake body cells // so we know to draw them // NB: Skip(1).Take(4) is Linq; it gives me the array left after // skipping the first item, then grabbing the next 4 (so in this // case misses the first and last). foreach (var cell in _snakeCells.Skip(1).Take(4)) { PlayField[cell.X, cell.Y] = FieldVals.SnakeBody; } } /// <summary> /// Just show a message and exit (can only lose right now) /// </summary> /// <param name="win"></param> void EndGame(bool win) { // Console.Clear(); // Console.WriteLine($"YOU DIED. Score: {_score} Snake Length: {_snakeBodyLen}"); // Console.ReadKey(); // Console.WriteLine("P to play again, Q to quit."); // var consoleKeyInfo = Console.ReadKey(); // if (consoleKeyInfo.Key == ConsoleKey.Q) // { // Environment.Exit(0); // } RunGame(); } public void RunGame() { _rnd = new Random(); //Console.Clear(); _score = 0; for (var i = 0; i < PlayfieldWidth; i++) { for (var j = 0; j < PlayfieldHeight; j++) { PlayField[i, j] = FieldVals.DontDraw; } } // create the initial snake cell coords (place it on playfield) SetUpSnake(); // start with an initial piece of food MakeNewFood(); timer1.Start(); // game loop; this was the easiest but might switch to Timer, etc. // function names should explain purpose // for (;/* ever */; ) // { // CheckForKeyboardCommand(); // AdjustGameSpeed(); // UpdatePlayfield(); // CheckForSnakeOutOfBounds(); // CheckForSnakeCollisionWithSelf(); // UpdateSnakeBodyPosition(); // CheckSnakeHasEatenFood(); // } } /// <summary> /// Set the console size appropriately & draw the border, leaving room for the score /// </summary> void DrawBorder( Graphics g) { for (var i = -1; i <= PlayfieldWidth; i++) { DrawCell(g, FieldVals.Border, i, -1); DrawCell(g, FieldVals.Border, i, PlayfieldHeight); } for (var i = -1; i <= PlayfieldHeight; i++) { DrawCell(g, FieldVals.Border, -1, i); DrawCell(g, FieldVals.Border, PlayfieldWidth, i); } } /// <summary> /// Go through every element of the 2d array, only drawing a cell /// if it has a value (other than 0). This way we only draw the /// cells that need to be updated. A bit like Invalidate() in GDO. /// Pretty self-explanatory; if a cell has a value, draw the character /// appropriate for it. The space is only used to overwrite the last /// piece of the snake's tail. /// </summary> void UpdatePlayfield( Graphics g) { DrawBorder( g); for (var i = 1; i < PlayfieldWidth - 1; i++) { for (var j = 1; j < PlayfieldHeight - 1; j++) { switch (PlayField[i, j]) { case FieldVals.Empty: DrawCell(g, FieldVals.Empty, i, j + 1); break; case FieldVals.SnakeHead: DrawCell( g, FieldVals.SnakeHead, i, j + 1); break; case FieldVals.SnakeBody: DrawCell(g, FieldVals.SnakeBody, i, j + 1); break; case FieldVals.SnakeFood: DrawCell(g, FieldVals.SnakeFood, i, j + 1); break; } } } PlayField[EraserPos.X, EraserPos.Y] = FieldVals.DontDraw; } public void DrawCell( Graphics g ,FieldVals cellType, int x, int y) { Color color = Color.Blue; switch (cellType) { case FieldVals.DontDraw: break; case FieldVals.Empty: break; case FieldVals.SnakeHead: color = Color.Blue; break; case FieldVals.SnakeBody: color = Color.DarkCyan; break; case FieldVals.SnakeFood: color = Color.Coral; break; case FieldVals.Border: color = Color.Black; break; } g.FillRectangle( new SolidBrush(color), x * CellSize + PlayfieldXOffset, y * CellSize + PlayfieldYOffset, CellSize, CellSize); } // From Microsoft sample private void WriteAt( Graphics g, string s, int x, int y) { using (var drawFont = new Font("Arial", 16)) using (var drawBrush = new SolidBrush(System.Drawing.Color.Black)) { g.DrawString(s, drawFont, drawBrush, x, y); } } private void Form1_Paint(object sender, PaintEventArgs e) { UpdatePlayfield( e.Graphics); DrawScore( e.Graphics); } } /// <summary> /// Codes representing keyboard keys. /// </summary> /// <remarks> /// Key code documentation: /// http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx /// </remarks> internal enum KeyCode { Left = 0x25, Up, Right, Down } /// <summary> /// Provides keyboard access. /// </summary> internal static class NativeKeyboard { /// <summary> /// A positional bit flag indicating the part of a key state denoting /// key pressed. /// </summary> const int KeyPressed = 0x8000; /// <summary> /// Returns a value indicating if a given key is pressed. /// </summary> /// <param name="key">The key to check.</param> /// <returns> /// <c>true</c> if the key is pressed, otherwise <c>false</c>. /// </returns> public static bool IsKeyDown(KeyCode key) { return (GetKeyState((int)key) & KeyPressed) != 0; } /// <summary> /// Gets the key state of a key. /// </summary> /// <param name="key">Virtual-key code for key.</param> /// <returns>The state of the key.</returns> [System.Runtime.InteropServices.DllImport("user32.dll")] static extern short GetKeyState(int key); } }
    43. Anthony Constantinou - CEO - CWM FX

      Any tips for Better Writing?

      Not only "open feeling", but you must consider the imaginations of others as well.
    44. Anthony Constantinou - CEO - CWM FX

      Programmer Art in Unity - 7 Techniques to Achieve Impressive Visuals Without an Artist

      Thanks for sharing the information. It is very helpful for everyone.
    45. In a perfect world, yeah, all of the above. But that's not realistic. The best answer is perhaps "the immediate community of a player". You help those around you, and it grows from there, with some of those you help teaming up with you to help others. E.g. you help a handful of kids with some learning through a learning (and testing) app, you help a homeless person you run into daily find a good place at a homeless shelter or even help him get back on his feet if possible. Small scale things, local. Or you may help someone somewhere help others, perhaps using some experience you have (like advising someone on how to help that homeless person find a good shelter and maybe get back on his feet). It's not a sword, but a thousand papercuts, if that phrase makes any sense here?
    46. lawnjelly

      Islands and Land

      Oo I'll have to try that out. 🙂 I'm not sure how expensive it will be yet, that reading back from the screen texture might be a thing.
    47. Totally. The Social Media platform will likely be a watered down Facebook thing, to make it recognizable and easy to navigate. The privacy and safety points are in the back of my head, but until I have a working suggestion for the game itself, they make no sense trying to design, of course....
    48. lawnjelly

      Checking a Height Value Repeatedly

      As with Zakwayda, I have tried very hard to understand what you were asking, but it has taken you a long time to even begin to pin down what you are trying to do, either through language difficulties or perhaps you didn't know what you wanted at the outset. It seems at this point you are trying to move a ball over a terrain. Is the ball rolling? Would a sphere be a better word? I'm getting the impression it cannot bounce. Is it moving only in the direction you provide, or can it roll sideways? We don't know, as you have been unable to ask the question precisely. What does the ball represent? Is it a ball, is it a player? We don't know. If you want to get more answers I strongly would suggest you start a new thread, and attempt to ask the question in a concise and precise fashion, perhaps get someone to help you who is more adept at the English language. There are plenty of folks here that are quite expert at physics (e.g. Dirk Gregorius, Randy Gaul etc), and I suspect part of the reason you haven't received more answers is that they would have to first spend ages try to decipher what you are trying to ask. Overall from what *I am guessing* you are looking for: The earlier suggestions I gave were all approximations. If you want to have a more accurate simulation I strongly suspect the answer you are looking for is: Use a physics engine Either a third party physics engine (preferably), or write one (or at least a subset). You expressed a wish for a 'simple' answer. Unfortunately some problems in games don't have a simple answer. This may not be a minor undertaking, as Zakwayda says many of the techniques are vulnerable to numerical error, and there are often special cases to debug and deal with. I would strongly advise if you really want to do this without a third party physics engine that you familiarize yourself with how they work (multiple bounces or slides per iteration), write your own at least for simple cases, and then you can apply the principles to come up with an approximate solution for this problem. You may be able to take advantage of some specifics of your case to make a more robust solution than a general case. For instance with a sphere, often you can treat the sphere path as a ray and 'push' the planes of collidees outwards to take account for the radius.
    49. That thing that strikes me is that it would likely have to be a very social design - something that connects people with those around them. Unfortunately, that means you also need to deal with the potential problems that could come along with that -- privacy, public safety, etc. Perhaps you could somehow leverage or build off one or more existing social media platforms?
    50. GVA1994

      Game audio production milestones

      Thank you!
    51. fleabay

      Assets used for free game?

      Some definitions of Personal Use are "No commercial use" and others say "No redistribution". It's a gray area, sorta like the spelling of grey. Get permission is your best bet, but I doubt the person could win in court with that dumb 'license'.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!