├── .gitattributes
├── .gitignore
├── LICENSE.md
├── README.md
└── platformerGame
├── AABB.cs
├── App
├── GameScene.cs
├── GameState.cs
├── MainMenu.cs
└── SfmlApp.cs
├── AssetLoader.cs
├── Camera.cs
├── Containers
├── GridOccupant.cs
├── IPool.cs
├── cQuadTree.cs
├── cSpatialCell.cs
└── cSpatialGrid.cs
├── DrawingBase.cs
├── Effects
└── EffectSystem.cs
├── GameObjects
├── Bird.cs
├── EntityGrid.cs
├── GameObjectGrid.cs
├── PickupInfo
│ └── cPickupInfo.cs
├── cBullet.cs
├── cCharacter.cs
├── cGameObject.cs
├── cMonster.cs
├── cPickupAble.cs
├── cPlayer.cs
└── cTurret.cs
├── GlobalClock.cs
├── IDrawable.cs
├── IGame.cs
├── Inventory
├── Weapons
│ ├── cMachineGun.cs
│ ├── cShotgun.cs
│ └── cWeapon.cs
├── cInventory.cs
└── cItem.cs
├── Map
├── cMapData.cs
├── cTile.cs
├── cTileLayer.cs
└── cTileMapRenderer.cs
├── MapCollider.cs
├── Particles
├── EmissionInfo.cs
├── IParticleContainer.cs
├── Particle.cs
├── cBaseParticleController.cs
├── cExplosionController.cs
├── cFireworksController.cs
├── cParticleManager.cs
├── cParticlePool.cs
├── cParticlePoolList.cs
└── cSprayController.cs
├── Program.cs
├── Regulator.cs
├── Rendering
├── RenderGroup.cs
├── cAnimatedSpriteRenderer.cs
├── cAnimationAssets.cs
├── cBaseRenderer.cs
└── cSpriteRenderer.cs
├── SfmlApp.cs
├── ShakeScreen.cs
├── StateBase
└── IState.cs
├── Utilities
├── AppMath.cs
├── AppRandom.cs
├── AppTimer.cs
├── Constants.cs
├── MyRect.cs
├── ProbabilityRoll.cs
├── Quaternion.cs
├── Utils.cs
├── cCollision.cs
├── cSatCollision.cs
└── cTimeInfo.cs
├── cAnimation.cs
├── cEnvironment.cs
├── cLight.cs
├── cLightSystem.cs
├── cPlayerInfo.cs
├── cSpriteState.cs
├── cSpriteStateController.cs
├── cWaterBlock.cs
├── cWorld.cs
├── constants.json
└── sfLine.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /platformerGame/bin
2 | /platformerGame/obj
3 | *.dll
4 | *.lib
5 | *.config
6 | *.sln
7 | *.csproj
8 | /.vs
9 | *VC.db
10 | *.opendb
11 | /platformerGame/UNUSED
12 | *.json
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | platformerGame
2 | =========
3 |
4 | ## 2D sidescrolling platformer experimental project, built with C# and [SFML.NET](https://www.sfml-dev.org/download/sfml.net/).
5 |
6 | This project is under development.
7 |
8 | ### Contains so far:
9 | * Scrolling map, player centered in camera
10 | * Simple light system
11 | * Character, bullet and particle collision detection with the map, and bullet-monster collision with hit handler
12 | * Particle systems
13 | * Wavy water blocks
14 | * Simple graphics, animation and sprite state control
15 | * Levels made by Tiled, loaded from .tmx files
16 | * Tile layers added
17 | * Monsters can drop "pickup-able" things
18 |
19 | 
20 |
21 | All rights reserved.
22 |
--------------------------------------------------------------------------------
/platformerGame/AABB.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.System;
7 | using SFML.Graphics;
8 | using platformerGame.Utilities;
9 |
10 | namespace platformerGame
11 | {
12 | class AABB
13 | {
14 | public Vector2f topLeft;
15 | public Vector2f rightBottom;
16 | public Vector2f center;
17 | public Vector2f dims; // full (not half) width and height
18 | public Vector2f halfDims; // half width and height
19 |
20 |
21 | public AABB()
22 | {
23 | topLeft = new Vector2f();
24 | rightBottom = new Vector2f();
25 | center = new Vector2f();
26 | dims = new Vector2f(0, 0);
27 | halfDims = new Vector2f(0, 0);
28 | }
29 |
30 | public AABB(float left, float top, float width, float height)
31 | {
32 | topLeft = new Vector2f(left, top);
33 | dims = new Vector2f(width, height);
34 | halfDims = dims / 2.0f;
35 | rightBottom = new Vector2f(topLeft.X + dims.X, topLeft.Y + dims.Y);
36 | center = new Vector2f(topLeft.X + halfDims.X, topLeft.Y + halfDims.Y);
37 | }
38 |
39 | public AABB(FloatRect rect) : this(rect.Left, rect.Top, rect.Width, rect.Height) { }
40 |
41 | public AABB(Vector2f top_left, Vector2f dims)
42 | {
43 | topLeft = top_left;
44 | this.dims = dims;
45 | halfDims = dims / 2.0f;
46 | rightBottom = new Vector2f(topLeft.X + dims.X, topLeft.Y + dims.Y);
47 | center = new Vector2f(topLeft.X + halfDims.X, topLeft.Y + halfDims.Y);
48 | }
49 |
50 | public AABB(AABB other)
51 | {
52 | SetDims(other.dims);
53 | SetPosByTopLeft(other.topLeft);
54 | }
55 |
56 | public void SetDims(Vector2f dims)
57 | {
58 | this.dims = dims;
59 | halfDims.X = dims.X / 2.0f;
60 | halfDims.Y = dims.Y / 2.0f;
61 | }
62 |
63 | public void SetPosByRightBottom(Vector2f new_right_bottom)
64 | {
65 | this.rightBottom = new_right_bottom;
66 |
67 | this.topLeft.X = new_right_bottom.X - dims.X;
68 | this.topLeft.Y = new_right_bottom.Y - dims.Y;
69 |
70 | this.center.X = new_right_bottom.X - halfDims.X;
71 | this.center.Y = new_right_bottom.Y - halfDims.Y;
72 | }
73 |
74 | public void SetPosByTopLeft(Vector2f top_left)
75 | {
76 | topLeft.X = top_left.X;
77 | topLeft.Y = top_left.Y;
78 |
79 | rightBottom.X = topLeft.X + dims.X;
80 | rightBottom.Y = topLeft.Y + dims.Y;
81 |
82 | center.X = topLeft.X + halfDims.X;
83 | center.Y = topLeft.Y + halfDims.Y;
84 | }
85 |
86 | public void SetPosByCenter(Vector2f center)
87 | {
88 | this.center.X = center.X;
89 | this.center.Y = center.Y;
90 |
91 | topLeft.X = this.center.X - halfDims.X;
92 | topLeft.Y = this.center.Y - halfDims.Y;
93 |
94 | rightBottom.X = this.center.X + halfDims.X;
95 | rightBottom.Y = this.center.Y + halfDims.Y;
96 | }
97 |
98 | public void Scale(Vector2f factors, Vector2f relative_to)
99 | {
100 | Transform t = Transform.Identity;
101 | t.Scale(factors, relative_to);
102 | FloatRect result = t.TransformRect(this.AsSfmlFloatRect());
103 | this.SetDims(new Vector2f(result.Width, result.Height));
104 | this.SetPosByTopLeft( new Vector2f(result.Left, result.Top));
105 | }
106 |
107 | public MyFloatRect AsMyFloatRect()
108 | {
109 | return new MyFloatRect(topLeft.X, topLeft.Y, dims.X, dims.Y);
110 | }
111 |
112 | public MyIntRect AsMyIntRect()
113 | {
114 | return new MyIntRect((int)topLeft.X, (int)topLeft.Y, (int)dims.X, (int)dims.Y);
115 | }
116 |
117 | public FloatRect AsSfmlFloatRect()
118 | {
119 |
120 | return new FloatRect(topLeft, dims);
121 | }
122 |
123 | public IntRect AsSfmlIntRect()
124 | {
125 | return new IntRect((int)topLeft.X, (int)topLeft.Y, (int)dims.X, (int)dims.Y);
126 | }
127 |
128 | public AABB ShallowCopy()
129 | {
130 | return (AABB)this.MemberwiseClone();
131 | }
132 |
133 | public AABB DeepCopy()
134 | {
135 | return new AABB(this);
136 | }
137 |
138 | ///
139 | /// for fast SA. collision detection (see @cSatCollision.cs)
140 | ///
141 | ///
142 | public Vector2f[] getLocalVertices()
143 | {
144 | // return Utilities.cSatCollision.BuildBox(dims.X, dims.Y);
145 |
146 | Vector2f[] b = new Vector2f[4]
147 | {
148 | new Vector2f(-halfDims.X, -halfDims.Y),
149 | new Vector2f(halfDims.X, -halfDims.Y),
150 | new Vector2f(halfDims.X, halfDims.Y),
151 | new Vector2f(-halfDims.X, halfDims.Y)
152 | };
153 |
154 | return b;
155 |
156 | }
157 |
158 | public Vector2f getTopRight()
159 | {
160 | return new Vector2f(topLeft.X + dims.X, topLeft.Y);
161 | }
162 |
163 | public Vector2f getLeftBottom()
164 | {
165 | return new Vector2f(topLeft.X, topLeft.Y + dims.Y);
166 | }
167 |
168 | public float diagonalLength()
169 | {
170 | return AppMath.getDiagonal(this.dims);
171 | }
172 |
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/platformerGame/App/GameState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.System;
7 | using SFML.Graphics;
8 | using SFML.Window;
9 |
10 | namespace platformerGame.App
11 | {
12 | ///
13 | /// A játék állapotát biztosító alaposztály. Ilyen állapot lehet pl. Főmenü, játék vagy új szint.
14 | ///
15 | abstract class GameState
16 | {
17 | protected SfmlApp appControllerRef = null;
18 | protected Camera camera = null;
19 | protected AssetContext resourceAssets = null;
20 |
21 | //protected View m_View;
22 | public GameState(SfmlApp app_ref)
23 | {
24 | appControllerRef = app_ref;
25 | resourceAssets = new AssetContext();
26 | //m_View = new View();
27 | }
28 | ///
29 | /// Az állapot induláskor kell végre hajtani
30 | ///
31 | public abstract void Enter();
32 |
33 | public virtual void BeforeUpdate() { }
34 | public abstract void UpdateFixed(float step_time);
35 | public abstract void UpdateVariable(float step_time = 1.0f);
36 |
37 | public abstract void Render(RenderTarget destination, float alpha);
38 |
39 | // Events
40 | public abstract void HandleMouseButtonPressed (MouseButtonEventArgs e);
41 | public abstract void HandleMouseButtonReleased (MouseButtonEventArgs e);
42 | public abstract void HandleMouseMoved (MouseMoveEventArgs e);
43 |
44 | public abstract void HandleKeyPressed (KeyEventArgs e);
45 | public abstract void HandleKeyReleased (KeyEventArgs e);
46 | public abstract void HandleTextEntered (TextEventArgs e);
47 |
48 | ///
49 | /// Must be called when exiting from a state
50 | ///
51 | public abstract void Exit();
52 |
53 | public Vector2f GetMousePosInWindow()
54 | {
55 | Vector2i m = Mouse.GetPosition(appControllerRef.MainWindow);
56 | Vector2f mf = appControllerRef.MainWindow.MapPixelToCoords(m);
57 |
58 | return mf; // new Vector2f(m.X, m.Y);
59 | }
60 |
61 | public Vector2f GetMousePos()
62 | {
63 | Vector2i iMp = Mouse.GetPosition(appControllerRef.MainWindow);
64 |
65 | Vector2f mousePos = appControllerRef.MainWindow.MapPixelToCoords(iMp, camera.View);
66 |
67 | return mousePos;
68 | }
69 |
70 | public SfmlApp AppController
71 | {
72 | get { return this.appControllerRef; }
73 | }
74 |
75 | public Camera Camera
76 | {
77 | get { return this.camera; }
78 | }
79 |
80 | public AssetContext Assets
81 | {
82 | get { return this.resourceAssets; }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/platformerGame/AssetLoader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 |
8 | using SFML.Graphics;
9 | using SFML.Audio;
10 | using SFML.System;
11 |
12 | using platformerGame.Utilities;
13 |
14 | namespace platformerGame
15 | {
16 | class AssetContext
17 | {
18 | public string[] FontNames { get; private set; }
19 | public string[] TextureNames { get; private set; }
20 | public string[] SoundNames { get; private set; }
21 |
22 | public Dictionary Textures { get; private set; }
23 | public Dictionary Fonts { get; private set; }
24 | public Dictionary SoundBuffers { get; private set; }
25 | public List Sounds { get; private set; }
26 |
27 | public AssetContext()
28 | {
29 | Textures = new Dictionary();
30 | Fonts = new Dictionary();
31 | SoundBuffers = new Dictionary();
32 | Sounds = new List();
33 | }
34 |
35 | public void LoadResources(string[] font_names = null, string[] textures_names = null, string[] sound_names = null)
36 | {
37 | // return Task.Factory.StartNew(() => { });
38 | this.ClearResources();
39 |
40 | this.FontNames = font_names;
41 | this.TextureNames = textures_names;
42 | this.SoundNames = sound_names;
43 |
44 | //loading fonts
45 | if (this.FontNames != null)
46 | {
47 | foreach (string fontName in this.FontNames)
48 | {
49 | Tuple data = AssetLoader.LoadFont(fontName);
50 | this.TryAddFont(data);
51 | }
52 | }
53 |
54 | //loading textures
55 | if (this.TextureNames != null)
56 | {
57 | foreach (string texName in this.TextureNames)
58 | {
59 | Tuple data = AssetLoader.LoadTexture(texName);
60 | this.TryAddTexture(data);
61 | }
62 | }
63 |
64 |
65 | //loading sounds
66 | if (this.SoundNames != null)
67 | {
68 | foreach (string soundName in this.SoundNames)
69 | {
70 | Tuple data = AssetLoader.LoadSound(soundName);
71 | this.TryAddSound(data);
72 | }
73 | }
74 | }
75 |
76 | public void TryAddFont(Tuple font_data)
77 | {
78 | if (false == Fonts.ContainsKey(font_data.Item1))
79 | {
80 | Fonts.Add(font_data.Item1, font_data.Item2);
81 | }
82 | }
83 |
84 | /*
85 | public string TryAddTexture(string path)
86 | {
87 | string id_name = AssetManager.GenerateIDFromFilePath(path);
88 | Texture t = AssetManager.LoadAndReturnTexture(path);
89 | this.TryAddTexture(new Tuple(id_name, t));
90 | return id_name;
91 | }
92 | */
93 |
94 | public void TryAddTexture(Tuple texture_data)
95 | {
96 | if (false == Textures.ContainsKey(texture_data.Item1))
97 | {
98 | Textures.Add(texture_data.Item1, texture_data.Item2);
99 | }
100 | }
101 |
102 | public void TryAddSound(Tuple sound_data)
103 | {
104 | if (false == SoundBuffers.ContainsKey(sound_data.Item1))
105 | {
106 | SoundBuffers.Add(sound_data.Item1, sound_data.Item2);
107 | }
108 | }
109 |
110 | public Font GetFont(string id)
111 | {
112 | Font f;
113 | if (Fonts.TryGetValue(id, out f))
114 | {
115 | return f;
116 | }
117 |
118 | return null;
119 | }
120 |
121 | public Texture GetTexture(string id)
122 | {
123 | Texture t;
124 | if (Textures.TryGetValue(id, out t))
125 | {
126 | return t;
127 | }
128 |
129 | return null;
130 | }
131 |
132 | public void PlaySound(string id, int volume = 50, Vector2f pos = default(Vector2f))
133 | {
134 | Sound s = new Sound(SoundBuffers[id]);
135 |
136 | s.Volume = volume;
137 | s.RelativeToListener = true;
138 | s.Position = new Vector3f(pos.X, 0.0f, pos.Y);
139 | //s.MinDistance = 5.0f;
140 | //s.Attenuation = 10.0f;
141 | s.Play();
142 |
143 | //sounds.Find(snd => snd.SoundBuffer == soundBuffers[id]);
144 |
145 | Sounds.Add(s);
146 | Sounds.RemoveAll(snd => snd.Status != SoundStatus.Playing);
147 | }
148 |
149 | public void ClearResources()
150 | {
151 | Textures.Clear();
152 | Fonts.Clear();
153 | SoundBuffers.Clear();
154 | Sounds.Clear();
155 | }
156 |
157 | public void Mix(AssetContext other_context)
158 | {
159 |
160 | }
161 | }
162 |
163 | class AssetLoader
164 | {
165 | public const string ROOT_PATH = "Resources/";
166 | public const string TEX_RESOURCE_PATH = "textures/";
167 | public const string TILESET_PATH = TEX_RESOURCE_PATH + "tilesets/";
168 | public const string FONT_RESOURCE_PATH = "fonts/";
169 | public const string SOUND_RESOURCE_PATH = "sounds/";
170 |
171 |
172 | static AssetLoader()
173 | {
174 | }
175 |
176 | public static string GenerateIDFromFilePath(string file_path)
177 | {
178 | file_path = file_path.Replace('\\', '/');
179 | int start = file_path.LastIndexOf('/')+1;
180 | int len = Math.Abs(file_path.LastIndexOf('.') - start);
181 | return file_path.Substring(start, len);
182 | }
183 |
184 | public static Tuple LoadFont(string file_name)
185 | {
186 | string path = Path.Combine(ROOT_PATH, FONT_RESOURCE_PATH, file_name);
187 | Font f = new Font(path);
188 |
189 | string id_name = GenerateIDFromFilePath(file_name);
190 |
191 | return new Tuple(id_name, f);
192 | }
193 |
194 | public static Tuple LoadSound(string file_name)
195 | {
196 | string path = Path.Combine(ROOT_PATH, SOUND_RESOURCE_PATH, file_name);
197 | SoundBuffer buffer; // = new SoundBuffer(path);
198 | string id_name = GenerateIDFromFilePath(file_name);
199 | buffer = new SoundBuffer(path);
200 | return new Tuple(id_name, buffer);
201 | }
202 |
203 | public static Tuple LoadTexture(string file_name)
204 | {
205 | string path = Path.Combine(ROOT_PATH, TEX_RESOURCE_PATH, file_name);
206 | Texture t = new Texture(path);
207 | t.Smooth = true;
208 | string id_name = GenerateIDFromFilePath(file_name);
209 |
210 | return new Tuple(id_name, t);
211 | }
212 |
213 | ///
214 | /// Just in case inline loader...
215 | ///
216 | ///
217 | ///
218 | public static Texture LoadAndReturnTexture(string file_name)
219 | {
220 | Texture t = new Texture(file_name);
221 | t.Smooth = true;
222 | return t;
223 | }
224 |
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/platformerGame/Camera.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 |
11 | namespace platformerGame
12 | {
13 | class Camera
14 | {
15 | ///
16 | /// Center point of the camera
17 | ///
18 | public Vector2f Target;
19 |
20 | ///
21 | /// If we want to move by offset, we can set here
22 | ///
23 | private Vector2f offset;
24 |
25 | ///
26 | /// Toggle for smooth camera transition
27 | ///
28 | public bool Smooth = true;
29 |
30 | ///
31 | /// Smoothness determines how quickly the transition will take place. Higher smoothness will reach the target position faster.
32 | ///
33 | public float Smoothness = 0.1f; //0.033f; 0.1666f
34 |
35 | ///
36 | /// Toggle for automatic position rounding. Useful if pixel sizes become inconsistent or font blurring occurs.
37 | ///
38 | public bool RoundPosition = false;
39 |
40 | public View View;
41 | public Vector2f PreviousPosition;
42 | public Vector2f ActualPosition;
43 | public Vector2f ViewPosition;
44 | private Vector2f originalSize;
45 |
46 | ///
47 | /// Gets or sets the current zoom level of the camera
48 | ///
49 | public float Zoom
50 | {
51 | get { return View.Size.X / originalSize.X; }
52 | set
53 | {
54 | View.Size = originalSize;
55 | View.Zoom(value);
56 | }
57 | }
58 |
59 | ///
60 | /// Calculates the area the camera should display
61 | ///
62 | public AABB Bounds
63 | {
64 | get { return new AABB(ActualPosition.X - (View.Size.X / 2.0f), ActualPosition.Y - (View.Size.Y / 2.0f), View.Size.X, View.Size.Y); }
65 |
66 | }
67 |
68 | public AABB ViewBounds
69 | {
70 | get { return new AABB(ViewPosition - (View.Size / 2.0f), View.Size); }
71 | }
72 |
73 | public Camera(FloatRect rect) : this(new View(rect)) { }
74 |
75 | public Camera(View view)
76 | {
77 | View = new View(view);
78 | Target = View.Size / 2.0f;
79 | originalSize = View.Size;
80 | ActualPosition = Target;
81 | PreviousPosition = ActualPosition;
82 | ViewPosition = ActualPosition;
83 | }
84 |
85 | public void SetOffset(Vector2f offset)
86 | {
87 | this.offset = offset;
88 | }
89 |
90 | /*
91 | public void Move(Vector2f offset)
92 | {
93 | ActualPosition += offset;
94 | }
95 | */
96 |
97 | public static Vector2f NullVec()
98 | {
99 | return new Vector2f(0.0f, 0.0f);
100 | }
101 |
102 | public void Update(Vector2f target, AABB region_bounds, float step_time = Constants.STEP_TIME)
103 | {
104 | this.Target = target;
105 | PreviousPosition = ActualPosition;
106 | if (Smooth)
107 | {
108 | Vector2f dir = AppMath.Vec2NormalizeReturn(Target - ActualPosition);
109 | float len = (float)AppMath.Vec2Distance(ActualPosition, Target);
110 | Vector2f vel = dir * (len * Smoothness);
111 | //AppMath.Vec2Truncate(ref vel, 2.0f);
112 | //vel += ShakeScreen.Offset;
113 | ActualPosition += vel;
114 | }
115 | else
116 | {
117 |
118 | ActualPosition = Target + ShakeScreen.Offset;
119 |
120 | }
121 |
122 | checkBounds(region_bounds);
123 | }
124 |
125 | /*
126 | public void Apply(RenderTarget target)
127 | {
128 | var center = ActualPosition;
129 |
130 | if (RoundPosition)
131 | {
132 | var pxSize = 1 * Zoom;
133 | center.X = cAppMath.RoundToNearest(ActualPosition.X, pxSize);
134 | center.Y = cAppMath.RoundToNearest(ActualPosition.Y, pxSize);
135 | }
136 |
137 | // offset fixes texture coord rounding
138 | var offset = 0.25f * Zoom;
139 | center.X += offset;
140 | center.Y += offset;
141 |
142 | View.Center = center;
143 | target.SetView(View);
144 | }
145 | */
146 |
147 | public void LocateActualPosition(Vector2f newPos)
148 | {
149 | ActualPosition = newPos;
150 | PreviousPosition = ActualPosition;
151 | }
152 |
153 | public void checkBounds(AABB region_bounds)
154 | {
155 | var cameraBounds = this.Bounds;
156 | /*
157 | if (RoundPosition)
158 | {
159 | var pxSize = 1 * Zoom;
160 | center.X = cAppMath.RoundToNearest(ActualPosition.X, pxSize);
161 | center.Y = cAppMath.RoundToNearest(ActualPosition.Y, pxSize);
162 | }
163 | */
164 |
165 |
166 | if (cameraBounds.topLeft.X < region_bounds.topLeft.X)
167 | ActualPosition = new Vector2f(region_bounds.topLeft.X + cameraBounds.halfDims.X, ActualPosition.Y);
168 | else
169 | if (cameraBounds.rightBottom.X > region_bounds.rightBottom.X)
170 | ActualPosition = new Vector2f(region_bounds.rightBottom.X - cameraBounds.halfDims.X, ActualPosition.Y);
171 |
172 |
173 | if (cameraBounds.topLeft.Y < region_bounds.topLeft.Y)
174 | ActualPosition = new Vector2f(ActualPosition.X, region_bounds.topLeft.Y + cameraBounds.halfDims.Y);
175 | else
176 | if (cameraBounds.rightBottom.Y > region_bounds.rightBottom.Y)
177 | ActualPosition = new Vector2f(ActualPosition.X, region_bounds.rightBottom.Y - cameraBounds.halfDims.Y);
178 |
179 | // cameraBounds.SetPosByCenter(ActualPosition);
180 | }
181 |
182 | public void DeployOn(RenderTarget target, float alpha, AABB region_bounds = null)
183 | {
184 |
185 | /*
186 | // offset fixes texture coord rounding
187 | var offset = 0.25f * Zoom;
188 | center.X += offset;
189 | center.Y += offset;
190 | */
191 | //Target = center;
192 | //ActualPosition = center;
193 | this.ViewPosition = AppMath.Interpolate(ActualPosition, PreviousPosition, alpha);
194 | this.View.Center = this.ViewPosition;
195 | target.SetView(this.View);
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/platformerGame/Containers/GridOccupant.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.System;
7 |
8 | namespace platformerGame.Containers
9 | {
10 | abstract class GridOccupant
11 | {
12 | public AABB Bounds { get; set; } = new AABB(0, 0, 1, 1);
13 | public Vector2i GridPosition { get; set; } = new Vector2i(0, 0);
14 |
15 | public GridOccupant()
16 | {
17 | }
18 |
19 | public GridOccupant(AABB _bounds)
20 | {
21 | Bounds = _bounds.ShallowCopy();
22 | }
23 |
24 | public virtual void Update(float step_time)
25 | { }
26 |
27 | public virtual bool isActive()
28 | {
29 | return true;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/platformerGame/Containers/IPool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Containers
8 | {
9 | interface IPool
10 | {
11 | List ListVisibles(AABB visible_region);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/platformerGame/Containers/cQuadTree.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 |
10 | using platformerGame.Utilities;
11 | using platformerGame.App;
12 |
13 | namespace platformerGame.Containers
14 | {
15 | class cQuadTree where T : GridOccupant
16 | {
17 | public const int MAX_OBJECTS = 10;
18 | public const int MAX_LEVEL = 4;
19 |
20 | List entities;
21 |
22 | static int numLevels = 0;
23 | int level;
24 | AABB bounds;
25 |
26 | RectangleShape shape;
27 | Text label;
28 | //cQuadTree* m_pParent;
29 |
30 | cQuadTree pNW; //north-west : left-top
31 | cQuadTree pNE; //north-east : right-top
32 | cQuadTree pSW; //south-west : left-bottom
33 | cQuadTree pSE; //south-east : right-bottom
34 |
35 | //sfml text
36 | //Text m_Text;
37 | GameState refState;
38 |
39 | public cQuadTree(int _level, AABB _bounds, GameState state)
40 | {
41 | this.refState = state;
42 | this.level = _level;
43 | this.bounds = _bounds;
44 |
45 | this.shape = new RectangleShape(bounds.dims);
46 | this.shape.Position = bounds.topLeft;
47 | this.shape.OutlineColor = Color.Red;
48 | this.shape.FillColor = Color.Transparent;
49 | this.shape.OutlineThickness = 1.0f;
50 |
51 | entities = new List();
52 |
53 | label = new Text();
54 |
55 | float xPos = bounds.rightBottom.X - level * 50;
56 | label.Position = new Vector2f(xPos, bounds.rightBottom.Y - 30);
57 |
58 |
59 | label.Font = state.Assets.GetFont("BGOTHL");
60 | label.CharacterSize = 24;
61 | label.Color = Color.White;
62 | label.Style = Text.Styles.Bold;
63 |
64 | SplitToRects();
65 | }
66 |
67 | public AABB Bounds
68 | {
69 | get { return bounds; }
70 | //set { bounds = value; }
71 | }
72 |
73 | public void SplitToRects()
74 | {
75 | if (level >= MAX_LEVEL)
76 | {
77 | return;
78 | }
79 |
80 | numLevels++;
81 |
82 | float subWidth = bounds.halfDims.X;
83 | float subHeight = bounds.halfDims.Y;
84 | float x = bounds.topLeft.X;
85 | float y = bounds.topLeft.Y;
86 |
87 | pNW = new cQuadTree(level + 1, new AABB(new Vector2f(x, y), new Vector2f(subWidth, subHeight)), refState);
88 | pNE = new cQuadTree(level + 1, new AABB(new Vector2f(x + subWidth, y), new Vector2f(subWidth, subHeight)), refState);
89 | pSW = new cQuadTree(level + 1, new AABB(new Vector2f(x, y + subHeight), new Vector2f(subWidth, subHeight)), refState);
90 | pSE = new cQuadTree(level + 1, new AABB(new Vector2f(x + subWidth, y + subHeight), new Vector2f(subWidth, subHeight)), refState);
91 |
92 | }
93 |
94 | public void Clear()
95 | {
96 | if (level == MAX_LEVEL)
97 | {
98 | entities.Clear();
99 | return;
100 | }
101 | else
102 | //if(this.level + 1 <= numLevels)
103 | {
104 | pNW.Clear();
105 | pNE.Clear();
106 | pSW.Clear();
107 | pSE.Clear();
108 | }
109 |
110 | if (entities.Count > 0)
111 | {
112 | entities.Clear();
113 | }
114 | }
115 |
116 | public bool Contains(cQuadTree child, T entity)
117 | {
118 | //bool b = (cCollision.OverlapAABB(child.Bounds, entity.Bounds));
119 | //bool b = pChild->GetBounds().AsFloatRect().intersects(pEntity->GetBoundingBox().AsFloatRect());
120 | return cCollision.OverlapAABB(child.Bounds, entity.Bounds);
121 | }
122 |
123 | public void AddEntity(T entity)
124 | {
125 | /*
126 | if (entities.Count >= MAX_OBJECTS)
127 | {
128 | SplitToRects();
129 | }
130 | */
131 |
132 | if (level >= MAX_LEVEL)
133 | {
134 | entities.Add(entity);
135 | return;
136 | }
137 |
138 |
139 | if (Contains(pNW, entity))
140 | {
141 | pNW.AddEntity(entity);
142 | //return;
143 | }
144 |
145 | if (Contains(pNE, entity))
146 | {
147 | pNE.AddEntity(entity);
148 | //return;
149 | }
150 |
151 | if (Contains(pSW, entity))
152 | {
153 | pSW.AddEntity(entity);
154 | //return;
155 | }
156 |
157 | if (Contains(pSE, entity))
158 | {
159 | pSE.AddEntity(entity);
160 | //return;
161 | }
162 |
163 | /*
164 | if (Contains(this, entity)) //contains
165 | {
166 | //logger << "Entity added to tree" << "";
167 | entities.Add(entity);
168 | //m_Text.setString( StringOf(m_Entities.size()) );
169 | }
170 | */
171 |
172 |
173 | }
174 | public List GetEntitiesAtPos(Vector2f pos)
175 | {
176 | if (level == MAX_LEVEL)
177 | return entities;
178 |
179 | List returnEntities = new List();
180 | List childReturnEntities = new List();
181 |
182 | FloatRect boundsRect = bounds.AsSfmlFloatRect();
183 |
184 | if (entities.Count > 0)
185 | {
186 | returnEntities = entities;
187 | }
188 |
189 | if (pos.X > boundsRect.Left + boundsRect.Width / 2.0f && pos.X < boundsRect.Left + boundsRect.Width)
190 | {
191 | if (pos.Y > boundsRect.Top + boundsRect.Height / 2.0f && pos.Y < boundsRect.Top + boundsRect.Height)
192 | {
193 | childReturnEntities = pSE.GetEntitiesAtPos(pos);
194 |
195 | returnEntities.AddRange(childReturnEntities);
196 |
197 | return returnEntities;
198 | }
199 | else
200 | if (pos.Y > boundsRect.Top && pos.Y <= boundsRect.Top + boundsRect.Height / 2.0f)
201 | {
202 | childReturnEntities = pNE.GetEntitiesAtPos(pos);
203 | returnEntities.AddRange(childReturnEntities);
204 | return returnEntities;
205 | }
206 | }
207 | else
208 | if (pos.X > boundsRect.Left && pos.X <= boundsRect.Left + boundsRect.Width / 2.0f)
209 | {
210 | if (pos.Y > boundsRect.Top + boundsRect.Height / 2.0f && pos.Y < boundsRect.Top + boundsRect.Height)
211 | {
212 | childReturnEntities = pSW.GetEntitiesAtPos(pos);
213 | returnEntities.AddRange(childReturnEntities);
214 | return returnEntities;
215 | }
216 | else
217 | if (pos.Y > boundsRect.Top && pos.Y <= boundsRect.Top + boundsRect.Height / 2.0f)
218 | {
219 | childReturnEntities = pNW.GetEntitiesAtPos(pos);
220 | returnEntities.AddRange(childReturnEntities);
221 | return returnEntities;
222 | }
223 | }
224 |
225 | return returnEntities;
226 | }
227 |
228 | public void DrawBounds(RenderTarget target)
229 | {
230 | label.DisplayedString = this.entities.Count.ToString();
231 | target.Draw(this.shape, new RenderStates(BlendMode.Alpha));
232 | target.Draw(label);
233 |
234 | if(this.level < MAX_LEVEL)
235 | {
236 | pNW.DrawBounds(target);
237 | pNE.DrawBounds(target);
238 | pSW.DrawBounds(target);
239 | pSE.DrawBounds(target);
240 | }
241 | }
242 |
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/platformerGame/Containers/cSpatialCell.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Containers
8 | {
9 | class cSpatialCell
10 | {
11 | List objects; // IDs of the stored objects
12 |
13 | int cellIndex; // the index of this cell in the spatial grid
14 |
15 | /*
16 | int gridX, gridY;
17 | cAABB bounds;
18 | */
19 |
20 | public cSpatialCell()
21 | {
22 | cellIndex = 0;
23 | objects = new List();
24 | }
25 |
26 | public cSpatialCell(int cell_index)
27 | {
28 | this.cellIndex = cell_index;
29 | objects = new List();
30 | }
31 |
32 | public void clear()
33 | {
34 | objects.Clear();
35 | }
36 |
37 | public void add(int object_id)
38 | {
39 | if(false == objects.Contains(object_id))
40 | objects.Add(object_id);
41 | }
42 |
43 | public void remove(int object_id)
44 | {
45 | objects.Remove(object_id);
46 | }
47 |
48 | public int[] getAll()
49 | {
50 | return objects.ToArray();
51 | }
52 |
53 |
54 | public int CellIndex
55 | {
56 | get { return cellIndex; }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/platformerGame/Containers/cSpatialGrid.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.System;
7 |
8 | namespace platformerGame.Containers
9 | {
10 | class cSpatialGrid
11 | {
12 | const int CELL_SIZE = 128; // 128 X 128 square
13 |
14 | cSpatialCell[] grid;
15 |
16 | Dictionary> cells;
17 |
18 | int height;
19 | int width;
20 | int numCells;
21 |
22 | public cSpatialGrid(int w, int h)
23 | {
24 | this.width = w;
25 | this.height = h;
26 | this.numCells = w * h;
27 | this.grid = new cSpatialCell[numCells];
28 | initCells();
29 | }
30 |
31 | public cSpatialGrid(Vector2f world_size)
32 | {
33 | this.width = (int)world_size.X / CELL_SIZE;
34 | this.height = (int)world_size.Y / CELL_SIZE;
35 | this.numCells = width * height;
36 | this.grid = new cSpatialCell[numCells];
37 | initCells();
38 |
39 | }
40 |
41 | private void initCells()
42 | {
43 | for(int i = 0; i < grid.Length; ++i)
44 | {
45 | grid[i] = new cSpatialCell(i);
46 | }
47 | }
48 | public void ClearAll()
49 | {
50 | foreach (var cell in grid)
51 | {
52 | cell.clear();
53 | }
54 | }
55 |
56 | public int GetIndexByXY(int x, int y)
57 | {
58 | int index = y * width + x;
59 | return index;
60 | }
61 |
62 | public int GetIndexByXY(Vector2i grid_pos)
63 | {
64 | int index = grid_pos.Y * width + grid_pos.X;
65 | return index; // index < 0 ? 0 : index >= numCells ? numCells -1 : index;
66 | }
67 |
68 | public cSpatialCell GetCellAtXY(int grid_x, int grid_y)
69 | {
70 | int index = grid_y * width + grid_x;
71 | return index >= 0 && index < numCells ? grid[index] : null;
72 | }
73 |
74 | public int GetCellIndexAtWorldPos(Vector2f world_pos)
75 | {
76 | Vector2i gridPos = ToGridPos(world_pos);
77 | return GetIndexByXY(gridPos);
78 | }
79 |
80 | public cSpatialCell getCell(Vector2f world_pos)
81 | {
82 | Vector2i gridPos = ToGridPos(world_pos);
83 | int index = GetIndexByXY(gridPos);
84 | return grid[index];
85 | }
86 |
87 | public Vector2i ToGridPos(Vector2f world_pos)
88 | {
89 | Vector2i ret = new Vector2i();
90 | ret.X = (int)(world_pos.X / CELL_SIZE);
91 | ret.Y = (int)(world_pos.Y / CELL_SIZE);
92 |
93 | ret.X = ret.X >= width ? width - 1 : ret.X < 0 ? 0 : ret.X;
94 | ret.Y = ret.Y >= height ? height - 1 : ret.Y < 0 ? 0 : ret.Y;
95 | return ret;
96 | }
97 |
98 | public Vector2f ToWorldPos(Vector2i grid_pos)
99 | {
100 | Vector2f ret = new Vector2f();
101 | ret.X = grid_pos.X * CELL_SIZE;
102 | ret.Y = grid_pos.Y * CELL_SIZE;
103 | return ret;
104 | }
105 |
106 | public void DeHandleObject(int id, AABB last_bounds)
107 | {
108 |
109 | }
110 |
111 | public void GetCells()
112 | {
113 | }
114 |
115 | public void HandleObject(int id, AABB bounds)
116 | {
117 | int topLeftIndex = GetCellIndexAtWorldPos(bounds.topLeft);
118 | int topRightIndex = GetCellIndexAtWorldPos(bounds.getTopRight());
119 | int bottomRightIndex = GetCellIndexAtWorldPos(bounds.rightBottom);
120 | int bottomLeftIndex = GetCellIndexAtWorldPos(bounds.getLeftBottom());
121 |
122 |
123 | if (topLeftIndex == bottomRightIndex)
124 | {
125 | grid[topLeftIndex].add(id);
126 | }
127 | else
128 | {
129 | if (topLeftIndex == bottomLeftIndex || bottomLeftIndex == bottomRightIndex)
130 | {
131 | grid[topLeftIndex].add(id);
132 | grid[bottomRightIndex].add(id);
133 | }
134 | else
135 | {
136 | grid[topLeftIndex].add(id);
137 | grid[topRightIndex].add(id);
138 | grid[bottomRightIndex].add(id);
139 | grid[bottomLeftIndex].add(id);
140 | }
141 | }
142 | }
143 |
144 | public int[] getObjectsAtWorldPos(Vector2f world_pos)
145 | {
146 | return getCell(world_pos)?.getAll();
147 | }
148 |
149 | public int[] getObjectsAtGridPos(int grid_x, int grid_y)
150 | {
151 | return GetCellAtXY(grid_x, grid_y)?.getAll();
152 | }
153 |
154 | public int[] getPossibleCollidableObjects(AABB bounds)
155 | {
156 | List all = new List();
157 | int topLeftIndex = GetCellIndexAtWorldPos(bounds.topLeft);
158 | int topRightIndex = GetCellIndexAtWorldPos(bounds.getTopRight());
159 | int bottomRightIndex = GetCellIndexAtWorldPos(bounds.rightBottom);
160 | int bottomLeftIndex = GetCellIndexAtWorldPos(bounds.getLeftBottom());
161 |
162 | if (topLeftIndex == bottomRightIndex)
163 | {
164 | all.AddRange(grid[topLeftIndex].getAll());
165 | }
166 | else
167 | {
168 | if (topLeftIndex == bottomLeftIndex || bottomLeftIndex == bottomRightIndex)
169 | {
170 | all.AddRange(grid[topLeftIndex].getAll());
171 | all.AddRange(grid[bottomRightIndex].getAll());
172 | }
173 | else
174 | {
175 | all.AddRange(grid[topLeftIndex].getAll());
176 | all.AddRange(grid[topRightIndex].getAll());
177 | all.AddRange(grid[bottomRightIndex].getAll());
178 | all.AddRange(grid[bottomLeftIndex].getAll());
179 | }
180 | }
181 | return all.ToArray();
182 | }
183 |
184 |
185 | public int[] getPossibleCollidableObjectsWithAdjacents(Vector2f position)
186 | {
187 | List all = new List();
188 | Vector2i gridPos = ToGridPos(position);
189 | int[] objs;
190 |
191 | if(null != (objs = getObjectsAtGridPos(gridPos.X - 1, gridPos.Y - 1)))
192 | {
193 | all.AddRange(objs);
194 | }
195 |
196 | if (null != (objs = getObjectsAtGridPos(gridPos.X, gridPos.Y - 1)))
197 | {
198 | all.AddRange(objs);
199 | }
200 |
201 | if (null != (objs = getObjectsAtGridPos(gridPos.X + 1, gridPos.Y - 1)))
202 | {
203 | all.AddRange(objs);
204 | }
205 |
206 | if (null != (objs = getObjectsAtGridPos(gridPos.X - 1, gridPos.Y)))
207 | {
208 | all.AddRange(objs);
209 | }
210 |
211 | if (null != (objs = getObjectsAtGridPos(gridPos.X, gridPos.Y)))
212 | {
213 | all.AddRange(objs);
214 | }
215 |
216 | if (null != (objs = getObjectsAtGridPos(gridPos.X + 1, gridPos.Y)))
217 | {
218 | all.AddRange(objs);
219 | }
220 |
221 | if (null != (objs = getObjectsAtGridPos(gridPos.X - 1, gridPos.Y + 1)))
222 | {
223 | all.AddRange(objs);
224 | }
225 |
226 | if (null != (objs = getObjectsAtGridPos(gridPos.X, gridPos.Y + 1)))
227 | {
228 | all.AddRange(objs);
229 | }
230 |
231 | if (null != (objs = getObjectsAtGridPos(gridPos.X + 1, gridPos.Y + 1)))
232 | {
233 | all.AddRange(objs);
234 | }
235 |
236 | return all.ToArray();
237 | }
238 |
239 | }
240 | }
241 |
--------------------------------------------------------------------------------
/platformerGame/Effects/EffectSystem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.System;
7 | using SFML.Graphics;
8 | using platformerGame.Rendering;
9 |
10 | namespace platformerGame.Effects
11 | {
12 | class AnimatedEffect
13 | {
14 | public Vector2f Centre { get; set; } // centre
15 | public cAnimation Animation { get; set; }
16 |
17 | public AnimatedEffect()
18 | {
19 | this.Centre = new Vector2f();
20 | this.Animation = null;
21 | }
22 | }
23 |
24 | class EffectSystem
25 | {
26 | List effects;
27 |
28 | public EffectSystem()
29 | {
30 | effects = new List();
31 | }
32 |
33 | public void Place(AnimatedEffect effect)
34 | {
35 | this.effects.Add(effect);
36 | }
37 |
38 | public void Place(Vector2f centre, string animation_name, bool repeat = false)
39 | {
40 | var effect = new AnimatedEffect();
41 | effect.Animation = new cAnimation(cAnimationAssets.Get(animation_name));
42 | effect.Animation.AnimData.Repeat = repeat;
43 | effect.Centre = centre;
44 | this.Place(effect);
45 | }
46 |
47 | public void PlaceGround(float x, float groundY, string animation_name)
48 | {
49 | var effect = new AnimatedEffect();
50 | effect.Animation = new cAnimation(cAnimationAssets.Get(animation_name));
51 |
52 | int h = effect.Animation.AnimData.ViewOffsetRect.Height;
53 | effect.Centre = new Vector2f(x, groundY - (h / 2.0f));
54 | this.Place(effect);
55 | }
56 |
57 | public void Update()
58 | {
59 | int eCount = effects.Count;
60 | for (int i = 0; i < eCount; ++i)
61 | {
62 | var e = effects[i];
63 |
64 | if (e.Animation.Active)
65 | {
66 | e.Animation.Update();
67 | continue;
68 | }
69 |
70 | effects.RemoveAt(i);
71 | i--;
72 | eCount = effects.Count;
73 |
74 | }
75 | }
76 |
77 | public void Render(RenderTarget destination)
78 | {
79 | foreach (var e in effects)
80 | {
81 | e.Animation.RenderCentered(destination, e.Centre);
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/Bird.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.GameObjects
8 | {
9 | class Bird : cGameObject
10 | {
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/EntityGrid.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 | using platformerGame.Containers;
11 |
12 | namespace platformerGame.GameObjects
13 | {
14 |
15 | class EntityGrid where T : GridOccupant
16 | {
17 | public const int ENTITY_GRID_SIZE = 128;
18 | public const int ENTITY_OVERSCAN = 128;
19 |
20 | protected List allEntities;
21 | //protected List visibleEntities; // on screen
22 |
23 | protected Dictionary> entityGrid;
24 | protected float cleanupTimer = 0.0f;
25 |
26 | public AABB GridArea { get; set; }
27 |
28 | public EntityGrid(Vector2f world_size)
29 | {
30 | GridArea = new AABB(0.0f, 0.0f, world_size.X, world_size.Y);
31 | this.initGrid();
32 | }
33 |
34 | public EntityGrid(AABB grid_bounds)
35 | {
36 | GridArea = grid_bounds;
37 | this.initGrid();
38 | }
39 |
40 | protected void initGrid()
41 | {
42 | this.allEntities = new List();
43 | //this.visibleEntities = new List();
44 | this.entityGrid = new Dictionary>();
45 | }
46 |
47 | public static Vector2i calcGridPos(Vector2f world_pos)
48 | {
49 | int x = (int)world_pos.X / ENTITY_GRID_SIZE;
50 | int y = (int)world_pos.Y / ENTITY_GRID_SIZE;
51 | return new Vector2i(x, y);
52 | }
53 |
54 | public List getInGridRect(int startX, int startY, int endX, int endY)
55 | {
56 | var pos = new Vector2i();
57 |
58 | List returner = new List();
59 |
60 | for (var y = startY; y <= endY; y++)
61 | {
62 | for (var x = startX; x <= endX; x++)
63 | {
64 | pos.X = x;
65 | pos.Y = y;
66 |
67 | List list;
68 | if (entityGrid.TryGetValue(pos, out list))
69 | {
70 | returner.AddRange(list);
71 | }
72 | }
73 | }
74 |
75 | return returner;
76 | }
77 |
78 | public List getEntitiesInRadius(Vector2f centre, float radius)
79 | {
80 | float sideLen = 2.0f * radius;
81 | AABB circleBoundRect = new AABB();
82 | circleBoundRect.SetDims(new Vector2f(sideLen, sideLen));
83 | circleBoundRect.SetPosByCenter(centre);
84 |
85 | return getEntitiesInArea(circleBoundRect);
86 | }
87 |
88 | public List getEntitiesNearby(Vector2f pos)
89 | {
90 | Vector2i gridPos = calcGridPos(pos);
91 | return this.getInGridRect(gridPos.X - 1, gridPos.Y - 1, gridPos.X + 1, gridPos.Y + 1);
92 | }
93 |
94 | public List getEntitiesInArea(AABB area)
95 | {
96 | FloatRect areaRect = area.AsSfmlFloatRect();
97 |
98 | var overscan = ENTITY_OVERSCAN;
99 | var gridSize = ENTITY_GRID_SIZE;
100 |
101 | FloatRect rect = new FloatRect(areaRect.Left - overscan, areaRect.Top - overscan,
102 | areaRect.Width + (overscan * 2), areaRect.Height + (overscan * 2));
103 |
104 | var startX = (int)rect.Left / gridSize;
105 | var startY = (int)rect.Top / gridSize;
106 | var width = (int)rect.Width / gridSize + 1;
107 | var height = (int)rect.Height / gridSize + 1;
108 |
109 | return this.getInGridRect(startX, startY, startX + width, startY + height);
110 | }
111 |
112 | public List GetAllEntities()
113 | {
114 | return this.allEntities;
115 | }
116 |
117 | public void AddEntities(IEnumerable entities)
118 | {
119 | foreach(var e in entities)
120 | {
121 | this.allEntities.Add(e);
122 | this.GridAdd(e);
123 | }
124 | }
125 |
126 | public void AddEntity(T e)
127 | {
128 | this.allEntities.Add(e);
129 | this.GridAdd(e);
130 | }
131 |
132 | public void RemoveEntity(T e)
133 | {
134 | // e.Destroy();
135 |
136 | GridRemove(e);
137 | this.allEntities.Remove(e);
138 | }
139 |
140 | public void RemoveAll()
141 | {
142 | foreach (var e in this.entityGrid)
143 | {
144 | e.Value.Clear();
145 | }
146 |
147 | this.entityGrid.Clear();
148 | this.allEntities.Clear();
149 | }
150 |
151 | protected void checkForCleanup(float step_time)
152 | {
153 | // cleanup grid
154 | cleanupTimer += step_time;
155 | // System.Diagnostics.Debug.WriteLine(cleanupTimer);
156 |
157 | if (cleanupTimer >= 6.0f)
158 | {
159 | entityGrid.RemoveAll(kv => kv.Value.Count == 0);
160 | cleanupTimer = 0.0f;
161 | }
162 | }
163 |
164 | protected void gridHandleUpdate(float step_time)
165 | {
166 | // update all entites
167 | Vector2i newGridPos = new Vector2i(0, 0);
168 |
169 | int eCount = allEntities.Count;
170 | for (int i = 0; i < eCount; ++i)
171 | {
172 | T entity = allEntities[i];
173 |
174 | if (entity.isActive())
175 | {
176 |
177 | // updateFunc?.Invoke(entity, step_time);
178 |
179 | entity.Update(step_time);
180 |
181 | var bounds = entity.Bounds;
182 | newGridPos = calcGridPos(bounds.center);
183 |
184 | if (!entity.GridPosition.Equals(newGridPos))
185 | {
186 | GridRemove(entity);
187 | entity.GridPosition = newGridPos;
188 | GridAdd(entity);
189 | }
190 |
191 | continue;
192 | }
193 |
194 | GridRemove(entity);
195 | allEntities.RemoveAt(i);
196 | i--;
197 | eCount = allEntities.Count;
198 | }
199 | }
200 |
201 | public virtual void Update(float step_time)
202 | {
203 | this.gridHandleUpdate(step_time);
204 | this.checkForCleanup(step_time);
205 | }
206 |
207 | protected void GridAdd(T e)
208 | {
209 | List list;
210 |
211 | if (false == entityGrid.TryGetValue(e.GridPosition, out list))
212 | {
213 | list = new List();
214 | list.Add(e);
215 | entityGrid.Add(e.GridPosition, list);
216 | return;
217 | }
218 |
219 | list.Add(e);
220 | }
221 |
222 | protected bool GridRemove(T e)
223 | {
224 | List list;
225 |
226 | if (entityGrid.TryGetValue(e.GridPosition, out list))
227 | {
228 | return list.Remove(e);
229 | }
230 |
231 |
232 | #if DEBUG
233 | System.Diagnostics.Debug.WriteLine(
234 | string.Format("Remove - FALSE"));
235 | #endif
236 |
237 | return false;
238 | }
239 |
240 | ///
241 | /// Filters visible entites and performs view position calculation for the visible ones.
242 | ///
243 | ///
244 | public IEnumerable filterVisibles(AABB view_region, Action executeOnTrue = null)
245 | {
246 | return this.allEntities.Where( e =>
247 | {
248 | executeOnTrue?.Invoke(e);
249 | return cCollision.OverlapAABB(e.Bounds, view_region);
250 | }
251 | );
252 |
253 | /*
254 | foreach (var e in allEntities)
255 | {
256 | if (cCollision.OverlapAABB(e.Bounds, view_region))
257 | {
258 | // e.CalculateViewPos(alpha);
259 | yield return e;
260 | }
261 | }
262 | */
263 | }
264 | }
265 |
266 | }
267 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/PickupInfo/cPickupInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 | using platformerGame.Rendering;
11 |
12 | namespace platformerGame.GameObjects.PickupInfo
13 | {
14 | delegate void PickupEffectFunction(cPlayer player);
15 |
16 | enum PickupType
17 | {
18 | UNKNOWN = -1,
19 | HEALTH = 0,
20 | ARMOR,
21 | AMMO,
22 | COIN_GOLD,
23 | COIN_SILVER,
24 | COIN_IRON
25 | }
26 |
27 |
28 | class cPickupInfo
29 | {
30 | PickupType pickupType;
31 | cBaseRenderer renderer;
32 | Vector2f hitRectSize;
33 | PickupEffectFunction effect;
34 |
35 |
36 | public cPickupInfo()
37 | {
38 | this.pickupType = PickupType.UNKNOWN;
39 | this.renderer = null;
40 | this.hitRectSize = new Vector2f(0, 0);
41 | this.effect = null;
42 | }
43 |
44 | public cPickupInfo(PickupType pickup_type, cBaseRenderer renderer, Vector2f hit_rect_size, PickupEffectFunction effect)
45 | {
46 | this.pickupType = pickup_type;
47 | this.renderer = renderer;
48 | this.hitRectSize = hit_rect_size;
49 | this.effect = effect;
50 | }
51 |
52 | public void applyEffect(cPlayer player)
53 | {
54 | effect(player);
55 | }
56 |
57 | public cPickupInfo ShallowCopy()
58 | {
59 | return (cPickupInfo)this.MemberwiseClone();
60 | }
61 |
62 | /*
63 | public cPickupInfo DeepCopy()
64 | {
65 | cPickupInfo copy = this.ShallowCopy();
66 |
67 | return copy;
68 | }
69 | */
70 |
71 | public PickupType PickupType
72 | {
73 | get { return pickupType; }
74 | }
75 |
76 | public cBaseRenderer Renderer
77 | {
78 | get { return renderer; }
79 | }
80 |
81 | public PickupEffectFunction Effect
82 | {
83 | get { return effect; }
84 | }
85 |
86 | public Vector2f HitRectSize
87 | {
88 | get { return this.hitRectSize; }
89 | }
90 | }
91 |
92 | class PickupEffects
93 | {
94 |
95 | private static Dictionary pickupTypes;
96 |
97 | private static ProbabilityRoll roller;
98 |
99 | private static Tuple[] pickupProbabilityTable;
100 |
101 | static PickupEffects()
102 | {
103 |
104 | }
105 |
106 | public static void Cleanup()
107 | {
108 | pickupTypes.Clear();
109 | roller.clear();
110 | }
111 |
112 | public static void InitPickupEffects(AssetContext assets)
113 | {
114 | /*
115 | int[] tcoords = { 0, 24, 48 };
116 | int tx = AppRandom.Chooose(tcoords);
117 | int ty = AppRandom.Chooose(tcoords, 2);
118 | */
119 | pickupTypes = new Dictionary()
120 | {
121 | [PickupType.HEALTH] = new cPickupInfo(PickupType.HEALTH, new cSpriteRenderer("pickups", new MyIntRect(0, 0, 24, 24), assets), new Vector2f(16, 22), AddHealth),
122 | [PickupType.ARMOR] = new cPickupInfo(PickupType.ARMOR, new cSpriteRenderer("pickups", new MyIntRect(0, 24, 24, 24), assets), new Vector2f(16, 22), AddArmor),
123 | [PickupType.AMMO] = new cPickupInfo(PickupType.AMMO, new cSpriteRenderer("pickups", new MyIntRect(24, 0, 24, 24), assets), new Vector2f(16, 22), AddAmmo),
124 | [PickupType.COIN_GOLD] = new cPickupInfo(PickupType.COIN_GOLD, new cAnimatedSpriteRenderer("coins-gold", new MyIntRect(0, 0, 16, 16), true), new Vector2f(16, 16), AddCoin),
125 | [PickupType.COIN_SILVER] = new cPickupInfo(PickupType.COIN_SILVER, new cAnimatedSpriteRenderer("coins-silver", new MyIntRect(0, 0, 16, 16), true), new Vector2f(16, 16), AddCoin),
126 | [PickupType.COIN_IRON] = new cPickupInfo(PickupType.COIN_IRON, new cAnimatedSpriteRenderer("coins-copper", new MyIntRect(0, 0, 16, 16), true), new Vector2f(16, 16), AddCoin)
127 | };
128 |
129 | pickupProbabilityTable = new Tuple[4]
130 | {
131 | new Tuple(50, PickupType.HEALTH),
132 | new Tuple(5, PickupType.ARMOR),
133 | new Tuple(5, PickupType.AMMO),
134 | new Tuple(40, PickupType.COIN_GOLD)
135 | };
136 |
137 | roller = new ProbabilityRoll();
138 | roller.seed(pickupProbabilityTable);
139 | }
140 |
141 | public static cPickupInfo get(PickupType type)
142 | {
143 | return pickupTypes[type];
144 | }
145 |
146 | public static cPickupInfo getWeighted()
147 | {
148 | return get( roller.roll() ).ShallowCopy();
149 | }
150 |
151 | private static void AddHealth(cPlayer player)
152 | {
153 | player.Health += 1;
154 | }
155 |
156 | private static void AddArmor(cPlayer player)
157 | {
158 | player.Health += 1;
159 | }
160 |
161 | private static void AddAmmo(cPlayer player)
162 | {
163 | player.Health += 1;
164 | }
165 |
166 | private static void AddCoin(cPlayer player)
167 | {
168 | player.Scene.Assets.PlaySound("coin_pickup1", 10);
169 | // TODO: player.Money += 1;
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/cBullet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 |
10 | using platformerGame.Utilities;
11 |
12 | namespace platformerGame.GameObjects
13 | {
14 | class BulletBreed
15 | {
16 | public Sprite sprite;
17 | public float startSpeed;
18 | public uint textureIntersectionOffset;
19 | public uint slugLength;
20 |
21 | public static Dictionary breeds;
22 |
23 | public BulletBreed()
24 | { }
25 |
26 | // must call somewhere
27 | public static void Init(AssetContext assets)
28 | {
29 | breeds = new Dictionary();
30 |
31 | BulletBreed b = new BulletBreed()
32 | {
33 | sprite = new Sprite( assets.GetTexture("bullet_light_green")),
34 | startSpeed = Constants.BULLET_START_SPEED,
35 | textureIntersectionOffset = 30,
36 | slugLength = 5
37 | };
38 |
39 | b.sprite.Scale = new Vector2f(0.5f, 0.5f);
40 | b.sprite.Origin = new Vector2f(b.sprite.TextureRect.Width - b.textureIntersectionOffset, b.sprite.TextureRect.Height / 2.0f);
41 | breeds.Add("simple-bullet", b);
42 |
43 | BulletBreed b2 = new BulletBreed()
44 | {
45 | sprite = new Sprite( assets.GetTexture("bullet3")),
46 | startSpeed = 250,
47 | textureIntersectionOffset = 1,
48 | slugLength = 1
49 | };
50 |
51 | b2.sprite.Scale = new Vector2f(0.7f, 0.7f);
52 | b2.sprite.Origin = new Vector2f(b2.sprite.TextureRect.Width, b2.sprite.TextureRect.Height / 2.0f);
53 |
54 | breeds.Add("turret-bullet", b2);
55 | }
56 |
57 | public static BulletBreed GetBreed(string id)
58 | {
59 | BulletBreed b;
60 | if(breeds.TryGetValue(id, out b))
61 | {
62 | return b;
63 | }
64 |
65 | return null;
66 | }
67 |
68 | public static void Cleanup()
69 | {
70 | breeds.Clear();
71 | }
72 | }
73 |
74 | class cBullet : cGameObject
75 | {
76 | const uint SLUG_LENGTH = 5;
77 |
78 | // 30, 15 pixels from the edge of the texture
79 | const uint TEXTURE_INTERSECTION_OFFSET = 30;
80 |
81 | BulletBreed breed;
82 |
83 | RenderStates blendMode = new RenderStates(BlendMode.Add);
84 |
85 | protected cGameObject owner;
86 | protected Vector2f oppositeDir;
87 | protected Vector2f intersection;
88 |
89 | protected Sprite sprite;
90 | protected bool alive;
91 | protected float alpha;
92 |
93 | ///
94 | ///
95 | ///
96 | ///
97 | /// position
98 | /// owner gameobject ex. cCharacter
99 | /// normalized vector of direction
100 | public cBullet(cGameObject owner, BulletBreed breed, Vector2f pos, Vector2f direction) : base(owner.Scene, pos)
101 | {
102 | this.owner = owner;
103 | this.breed = breed;
104 |
105 | this.alive = true;
106 | this.alpha = 255.0f;
107 | // proci határozza meg, hogy milyen alaplap foglalat és milyen RAM!!
108 | this.heading = direction;
109 | this.Bounds = new AABB();
110 | this.Bounds.SetDims(new Vector2f(1.0f, 1.0f));
111 | this.oppositeDir = new Vector2f(-this.heading.X * breed.slugLength, -this.heading.Y * breed.slugLength);
112 | this.intersection = new Vector2f(0.0f, 0.0f);
113 | this.Bounds.SetPosByTopLeft(pos);
114 | this.velocity.X = this.heading.X * breed.startSpeed;
115 | this.velocity.Y = this.heading.Y * breed.startSpeed;
116 | orientation = AppMath.GetAngleOfVector(heading);
117 |
118 | this.sprite = new Sprite(this.breed.sprite); // bullet_yellow_sm; bullet_light_gree
119 | this.sprite.Rotation = (float)AppMath.RadianToDegress(this.orientation);
120 | }
121 |
122 | public cGameObject Owner
123 | {
124 | get { return owner; }
125 | }
126 |
127 | public bool checkCollisionWithWorld(cWorld world, ref Vector2f intersectionOut)
128 | {
129 | Vector2i posA = new Vector2i((int)this.lastPosition.X, (int)this.lastPosition.Y); //world.ToMapPos(this.lastPosition);
130 | Vector2i posB = new Vector2i((int)this.position.X, (int)this.position.Y); // world.ToMapPos(this.Position);
131 | bool collided = false;
132 |
133 | Vector2f intersectionPoint = new Vector2f(0.0f, 0.0f);
134 | AppMath.Raytrace(posA.X, posA.Y, posB.X, posB.Y,
135 | (x, y) =>
136 | {
137 |
138 | collided = world.IsWallAtPos(new Vector2f(x, y)); //world.GetCurrentLevel.IsObstacleAtPos(x, y);
139 |
140 | intersectionPoint.X = x; // = world.ToWorldPos(new Vector2i(x, y));
141 | intersectionPoint.Y = y;
142 |
143 |
144 | return collided;
145 | }
146 | );
147 |
148 | intersectionOut.X = intersectionPoint.X;
149 | intersectionOut.Y = intersectionPoint.Y;
150 | return collided;
151 | }
152 |
153 | public override void Update(float step_time)
154 | {
155 | lastPosition.X = position.X;
156 | lastPosition.Y = position.Y;
157 | //velocity.Y += (Constants.GRAVITY/2.0f) * step_time;
158 | position.X += velocity.X * step_time;
159 | position.Y += velocity.Y * step_time;
160 |
161 |
162 |
163 | this.Bounds.SetPosByTopLeft(position);
164 | this.hitCollisionRect = Bounds;
165 |
166 | var world = Scene.World;
167 |
168 | world.collideSAT(this, step_time, false, () => {
169 | velocity = new Vector2f(0.0f, 0.0f);
170 | this.Scene.QueueAction(() =>
171 | {
172 | this.Scene.Effects.Place(position, "simple-explosion2");
173 | });
174 |
175 | this.kill();
176 | });
177 |
178 | /*
179 | if (this.checkCollisionWithWorld(owner.Scene.World, ref intersection))
180 | {
181 | //this.alive = false; // if not set to false, bullets will be shown
182 | position.X = intersection.X;
183 | position.Y = intersection.Y;
184 | velocity = new Vector2f(0.0f, 0.0f);
185 | //cAssetManager.playSound("wallhit", 5);
186 |
187 | this.Scene.QueueAction(() =>
188 | {
189 | this.Scene.Effects.Place(intersection, "simple-explosion2");
190 | });
191 |
192 | this.kill();
193 | }
194 | */
195 |
196 | if (!AppMath.Vec2IsZero(velocity))
197 | {
198 | heading = AppMath.Vec2NormalizeReturn(velocity);
199 | //orientation = cAppMath.GetAngleOfVector(heading);
200 | //Side = Math->Vec2Perp(Heading);
201 | }
202 | }
203 |
204 | public void kill()
205 | {
206 | this.alive = false;
207 | }
208 |
209 | public bool Alive
210 | {
211 | get { return this.alive; }
212 | }
213 |
214 | public override bool isActive()
215 | {
216 | return this.alive;
217 | // && this.alpha > 1.0f;
218 | //&& cCollision.IsPointInsideBox(this.position, this.owner.Scene.World.WorldBounds);
219 | }
220 |
221 | public override void Render(RenderTarget destination)
222 | {
223 | //this.Bounds.SetPosByTopLeft(this.viewPosition);
224 | this.sprite.Position = this.viewPosition;
225 | Color c = this.sprite.Color;
226 | c.A = (byte)this.alpha;
227 | this.sprite.Color = c;
228 |
229 | //sprite.Rotation = (float)cAppMath.RadianToDegress(orientation);
230 |
231 | destination.Draw(this.sprite, this.blendMode);
232 | //cRenderFunctions.DrawLine(destination, this.viewPosition, this.viewPosition + this.oppositeDir, 2.0f, new Color(237, 247, 89, 255), BlendMode.Add);
233 | //cRenderFunctions.DrawRectangleShape(destination, this.Bounds, Color.Green, BlendMode.Add); //cAppMath.RadianToDegress(this.orientation)
234 | }
235 |
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/cGameObject.cs:
--------------------------------------------------------------------------------
1 | using SFML.System;
2 | using SFML.Graphics;
3 |
4 | using platformerGame.Utilities;
5 | using platformerGame.Containers;
6 | using platformerGame.App;
7 |
8 | namespace platformerGame.GameObjects
9 | {
10 | class cGameObject : GridOccupant, IDrawable
11 | {
12 | protected int id;
13 | protected static int m_NextValidID;
14 |
15 | protected GameScene pscene;
16 |
17 | protected Vector2f position;
18 | protected Vector2f lastPosition;
19 | protected Vector2f viewPosition; // interpolációhoz
20 |
21 | protected Vector2f velocity;
22 | protected Vector2f acceleration;
23 | protected Vector2f force;
24 |
25 | protected Vector2f facing; // milyen irányba "néz"
26 | protected Vector2f heading; //milyen irányba halad
27 |
28 | protected Vector2f aabbOffset;
29 | protected double orientation;
30 | public float MaxSpeed { get; set; }
31 | public float SlowDown { get; set; }
32 |
33 | ///
34 | /// For Debug purposes.
35 | ///
36 | public bool Marked { get; set; }
37 |
38 | protected Vector2f viewSize;
39 | //protected cAABB boundingBox;
40 |
41 |
42 | protected float mass;
43 |
44 | protected bool movAble;
45 |
46 | protected AABB hitCollisionRect;
47 | protected float boundingRadius = 16.0f; // for separetion
48 |
49 | public cGameObject() : base()
50 | {
51 | pscene = null;
52 | position = new Vector2f(0.0f, 0.0f);
53 | lastPosition = new Vector2f(0.0f, 0.0f);
54 | viewPosition = new Vector2f(0.0f, 0.0f);
55 |
56 | velocity = new Vector2f(0.0f, 0.0f);
57 | acceleration = new Vector2f(0.0f, 0.0f);
58 | force = new Vector2f(0.0f, 0.0f);
59 | MaxSpeed = 0.0f;
60 | SlowDown = 1.0f;
61 | orientation = 0.0;
62 | mass = 1.0f;
63 | movAble = true;
64 | hitCollisionRect = new AABB();
65 |
66 | this.Marked = false;
67 | id = GetNextValidID();
68 | }
69 |
70 | public cGameObject(GameScene scene, Vector2f pos) : base()
71 | {
72 | pscene = scene;
73 | position = pos;
74 | lastPosition = pos;
75 | viewPosition = pos;
76 |
77 | this.GridPosition = new Vector2i(0, 0);
78 |
79 | velocity = new Vector2f(0.0f, 0.0f);
80 | acceleration = new Vector2f(0.0f, 0.0f);
81 | force = new Vector2f(0.0f, 0.0f);
82 | orientation = 0.0;
83 | mass = 1.0f;
84 | movAble = true;
85 | hitCollisionRect = new AABB();
86 | this.Marked = false;
87 | id = GetNextValidID();
88 | }
89 |
90 | public void Create()
91 | {
92 | this.GridPosition = EntityGrid.calcGridPos(this.Bounds.center);
93 | }
94 |
95 | protected static int GetNextValidID()
96 | {
97 | return m_NextValidID++;
98 | }
99 |
100 | public Vector2f ViewSize
101 | {
102 | get { return viewSize; }
103 | set { viewSize = value; }
104 | }
105 |
106 | public AABB HitCollisionRect
107 | {
108 | get { return hitCollisionRect; }
109 | set { hitCollisionRect = value; }
110 | }
111 |
112 | public int ID
113 | {
114 | get { return id; }
115 | }
116 | public GameScene Scene
117 | {
118 | get { return pscene; }
119 | }
120 |
121 | public Vector2f Position
122 | {
123 | get
124 | {
125 | return position;
126 | }
127 |
128 | set
129 | {
130 | position = value;
131 | }
132 | }
133 |
134 | public Vector2f LastPosition
135 | {
136 | get
137 | {
138 | return lastPosition;
139 | }
140 |
141 | set
142 | {
143 | lastPosition = value;
144 | }
145 | }
146 |
147 | public Vector2f ViewPosition
148 | {
149 | get
150 | {
151 | return viewPosition;
152 | }
153 |
154 | set
155 | {
156 | viewPosition = value;
157 | }
158 | }
159 |
160 | public Vector2f Velocity
161 | {
162 | get
163 | {
164 | return velocity;
165 | }
166 |
167 | set
168 | {
169 | velocity = value;
170 | }
171 | }
172 |
173 | public Vector2f Acceleration
174 | {
175 | get
176 | {
177 | return acceleration;
178 | }
179 |
180 | set
181 | {
182 | acceleration = value;
183 | }
184 | }
185 |
186 | public Vector2f Force
187 | {
188 | get
189 | {
190 | return force;
191 | }
192 |
193 | set
194 | {
195 | force = value;
196 | }
197 | }
198 |
199 | public Vector2f Heading
200 | {
201 | get
202 | {
203 | return heading;
204 | }
205 |
206 | set
207 | {
208 | heading = value;
209 | }
210 | }
211 |
212 | public Vector2f Facing
213 | {
214 | get
215 | {
216 | return facing;
217 | }
218 |
219 | set
220 | {
221 | facing = value;
222 | }
223 | }
224 |
225 | public Vector2f AabbOffset
226 | {
227 | get
228 | {
229 | return aabbOffset;
230 | }
231 |
232 | set
233 | {
234 | aabbOffset = value;
235 | }
236 | }
237 |
238 | public double Orientation
239 | {
240 | get
241 | {
242 | return orientation;
243 | }
244 |
245 | set
246 | {
247 | orientation = value;
248 | }
249 | }
250 |
251 | public float Mass
252 | {
253 | get { return this.mass; }
254 | set { this.mass = value; }
255 | }
256 |
257 | public bool MovAble
258 | {
259 | get { return this.movAble; }
260 | set { this.movAble = value; }
261 | }
262 |
263 | public bool Unmovable
264 | {
265 | get { return !this.movAble; }
266 | }
267 |
268 | public float BoundingRadius
269 | {
270 | get { return this.boundingRadius; }
271 | set { this.boundingRadius = value; }
272 | }
273 |
274 | public void AddForce(Vector2f impulse)
275 | {
276 | this.force += impulse;
277 | }
278 |
279 | public void CalculateViewPos(float alpha)
280 | {
281 | viewPosition = AppMath.Interpolate(position, lastPosition, alpha);
282 | }
283 |
284 | public virtual void Render(RenderTarget destination)
285 | { }
286 |
287 | public Vector2f GetCenterViewPos()
288 | {
289 | return viewPosition + Bounds.halfDims;
290 | }
291 |
292 | public Vector2f GetCenterPos()
293 | {
294 | return position + Bounds.halfDims;
295 | }
296 |
297 | public void MoveBy(Vector2f offset)
298 | {
299 | //this.lastPosition = position;
300 | this.position.X += offset.X;
301 | this.position.Y += offset.Y;
302 | }
303 |
304 | public void AddVelocity(Vector2f offset)
305 | {
306 | this.velocity.X += offset.X;
307 | this.velocity.Y += offset.Y;
308 | }
309 |
310 | public virtual void Kill(cGameObject by)
311 | { }
312 |
313 |
314 | public static cGameObject fromParticle(Particle p)
315 | {
316 | cGameObject go = new cGameObject();
317 | go.Position = p.Pos;
318 | go.LastPosition = p.LastPos;
319 | go.Velocity = p.Vel;
320 | go.viewPosition = p.ViewPos;
321 | go.Bounds.SetDims(new Vector2f(2.0f, 2.0f));
322 | go.Bounds.SetPosByCenter(p.Pos);
323 | go.mass = 1.0f;
324 | go.movAble = true;
325 | go.HitCollisionRect = go.Bounds.ShallowCopy();
326 | return go;
327 | }
328 |
329 | public static cGameObject MakeWall(AABB box)
330 | {
331 | cGameObject go = new cGameObject();
332 | go.Position = box.center;
333 | go.LastPosition = go.Position;
334 | go.Velocity = new Vector2f(0.0f, 0.0f);
335 | go.ViewPosition = go.Position;
336 | //box.SetDims(new Vector2f(Constants.TILE_SIZE, Constants.TILE_SIZE));
337 | go.Bounds = box;
338 | go.HitCollisionRect = box;
339 | go.MovAble = false; // important!
340 | go.Mass = 0.0f;
341 | return go;
342 | }
343 | }
344 | }
345 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/cPickupAble.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.Graphics;
7 | using SFML.System;
8 |
9 | using platformerGame.Utilities;
10 | using platformerGame.GameObjects.PickupInfo;
11 | using platformerGame.Rendering;
12 | using platformerGame.App;
13 |
14 | namespace platformerGame.GameObjects
15 | {
16 | class cPickupAble : cGameObject
17 | {
18 |
19 | cPickupInfo pickup;
20 |
21 | cBaseRenderer renderer;
22 |
23 | bool pickedUp;
24 | bool pulling;
25 |
26 | const float EMIT_SPEED = 150.0f;
27 | const int MAX_PULL_DISTANCE = 80;
28 | const int PULL_FORCE = 10;
29 |
30 | public cPickupAble() : base()
31 | { }
32 |
33 | ///
34 | /// If pickup type is unknown (not specified), generate one by weights
35 | ///
36 | ///
37 | ///
38 | ///
39 | ///
40 | public cPickupAble(GameScene scene, Vector2f pos, Vector2f emit_direction, PickupType type = PickupType.UNKNOWN) : base(scene, pos)
41 | {
42 | pickup = type == PickupType.UNKNOWN ? PickupEffects.getWeighted() : PickupEffects.get(type);
43 | this.init(pos, emit_direction);
44 | }
45 |
46 | private void init(Vector2f pos, Vector2f emit_direction)
47 | {
48 | this.pickedUp = pulling = false;
49 | this.heading = emit_direction;
50 |
51 | this.renderer = pickup.Renderer.DeepCopy();
52 |
53 | this.Bounds = new AABB();
54 | this.Bounds.SetDims(this.pickup.HitRectSize);
55 | this.Bounds.SetPosByCenter(pos);
56 | this.HitCollisionRect = Bounds.ShallowCopy();
57 |
58 | this.MaxSpeed = EMIT_SPEED * 2; //*2
59 | this.mass = 100.0f;
60 |
61 | this.velocity.X = this.heading.X * EMIT_SPEED;
62 | this.velocity.Y = this.heading.Y * EMIT_SPEED;
63 | orientation = AppMath.GetAngleOfVector(heading);
64 | }
65 |
66 | public override bool isActive()
67 | {
68 | return (false == pickedUp);
69 | }
70 |
71 | protected void checkCollisionWithWorld(float step_time)
72 | {
73 | cWorld world = Scene.World;
74 |
75 | if (false == pulling)
76 | {
77 | pscene.World.collideSAT(this, step_time);
78 |
79 | /*
80 | // check collisions with world
81 | List wallsPossibleColliding = world.getCollidableBlocks(Bounds);
82 |
83 | // we must check this, because we need to iterate through the possible
84 | // colliding tiles from other direction according to this condition
85 | if (velocity.X > 0.0f)
86 | {
87 | for (int i = 0; i < wallsPossibleColliding.Count; ++i)
88 | {
89 | cGameObject wallObject = cGameObject.MakeWall(wallsPossibleColliding[i]);
90 | if (cSatCollision.checkAndResolve(this, wallObject, step_time, true))
91 | {
92 | return;
93 | }
94 | }
95 | }
96 | else
97 | {
98 | // we have to iterate from "end" to the "start" in order to have the last colliding block below us
99 | for (int i = wallsPossibleColliding.Count-1; i >= 0; --i)
100 | {
101 | cGameObject wallObject = cGameObject.MakeWall(wallsPossibleColliding[i]);
102 | if (cSatCollision.checkAndResolve(this, wallObject, step_time, true))
103 | {
104 | return;
105 | }
106 |
107 | }
108 | }
109 | */
110 | }
111 | }
112 |
113 | public override void Update(float step_time)
114 | {
115 | this.renderer.Update(step_time);
116 |
117 | cPlayer player = Scene.Player;
118 | if (this.pulling)
119 | {
120 | Vector2f predicted = AppMath.Vec2NormalizeReturn((player.Bounds.center + (player.Velocity * step_time)) - this.Bounds.center);
121 | // pull pickup
122 | //Vector2f toPlayer = cAppMath.Vec2NormalizeReturn(player.Bounds.center - this.Bounds.center);
123 |
124 | // G * ((m1*m2) / (d*d))
125 | float f = PULL_FORCE * 150f; // * (100000.0f / ( d*d) );
126 | this.AddForce(predicted * f);
127 | }
128 | /*
129 | else
130 | {
131 | this.pulling = false;
132 | }
133 | */
134 |
135 | // applying some gravity
136 | force.Y += (false == pulling) ? (Constants.GRAVITY * 40.0f * step_time) : 0.0f;
137 |
138 | velocity.X += force.X * step_time;
139 | velocity.Y += force.Y * step_time;
140 |
141 | //velocity.X = Math.Abs(velocity.X) < 0.05f ? 0.0f : velocity.X;
142 | //velocity.Y = Math.Abs(velocity.Y) < 0.05f ? 0.0f : velocity.Y;
143 |
144 | double len = AppMath.Vec2Length(velocity);
145 | if (len < 0.1)
146 | {
147 | velocity = new Vector2f(0.0f, 0.0f);
148 |
149 | }
150 |
151 | AppMath.Vec2Truncate(ref velocity, MaxSpeed);
152 |
153 | // get more precise result calling it here (because of the updated velocity)
154 | // instead of calling at the beginning of this update method
155 | checkCollisionWithWorld(step_time);
156 |
157 | lastPosition = position;
158 | position.X += velocity.X * step_time;
159 | position.Y += velocity.Y * step_time;
160 |
161 | Bounds.SetPosByCenter(position);
162 | this.hitCollisionRect = Bounds;
163 |
164 | if (!AppMath.Vec2IsZero(velocity))
165 | {
166 | heading = AppMath.Vec2NormalizeReturn(velocity);
167 | orientation = AppMath.GetAngleOfVector(heading);
168 | }
169 |
170 | force = new Vector2f(0.0f, 0.0f);
171 | }
172 |
173 | public override void Render(RenderTarget destination)
174 | {
175 | //sprite.Position = ViewPosition;
176 | //sprite.Rotation = (float)cAppMath.RadianToDegress(orientation);
177 | //destination.Draw(this.sprite, new RenderStates(BlendMode.Alpha));
178 |
179 | this.renderer.Draw(destination, ViewPosition);
180 |
181 | /*
182 | RectangleShape rs = new RectangleShape();
183 | rs.Size = collidingTile.dims;
184 | rs.Position = collidingTile.topLeft;
185 | rs.FillColor = new Color(255, 0, 0, 150);
186 | for(int i = 0; i< walls.Count; i++)
187 | {
188 | rs.Position = walls[i].topLeft;
189 | destination.Draw(rs, new RenderStates(BlendMode.Alpha));
190 | }
191 | */
192 | }
193 |
194 | public virtual void checkContactWithPlayer()
195 | {
196 | cPlayer player = Scene.Player;
197 |
198 | float d = (float)AppMath.Vec2Distance(player.Bounds.center, this.Bounds.center);
199 |
200 | if (!this.pulling)
201 | {
202 | this.pulling = d <= MAX_PULL_DISTANCE;
203 | }
204 |
205 | if (!pickedUp && cCollision.OverlapAABB(player.Bounds, this.HitCollisionRect))
206 | {
207 | player.pickUp(pickup);
208 | pickedUp = true;
209 | }
210 | }
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/cPlayer.cs:
--------------------------------------------------------------------------------
1 | using SFML.Graphics;
2 | using SFML.System;
3 |
4 | using platformerGame.Inventory.Weapons;
5 | using platformerGame.Utilities;
6 | using platformerGame.GameObjects.PickupInfo;
7 | using platformerGame.App;
8 |
9 | namespace platformerGame.GameObjects
10 | {
11 | class cPlayer : cCharacter
12 | {
13 | cWeapon weapon;
14 | Text healthText;
15 |
16 | cLight fireLight;
17 |
18 | public cPlayer(GameScene scene, Vector2f pos) : base(scene, pos)
19 | {
20 | fireLight = new cLight();
21 | fireLight.Pos = this.Bounds.center;
22 | fireLight.Bleed = 10.0f;
23 | fireLight.Radius = 120.0f;
24 | fireLight.LinearizeFactor = 0.96f;
25 | fireLight.OriginalColor = new Color(136, 216, 176);
26 | fireLight.Color = new Color(136, 216, 176);
27 | fireLight.TurnOff();
28 | this.Scene.LightMap.AddStaticLight(fireLight);
29 |
30 |
31 | p_followLight = new cLight();
32 | p_followLight.Pos = this.Bounds.center;
33 | p_followLight.Radius = 160.0f;
34 | p_followLight.LinearizeFactor = 0.9f;
35 | p_followLight.OriginalColor = new Color(240, 219, 164);
36 | p_followLight.Color = new Color(240, 219, 164);
37 | // p_followLight.TurnOff();
38 | this.Scene.LightMap.AddStaticLight(p_followLight);
39 |
40 | this.weapon = // new cMachineGun(this, Constants.DEFAULT_WEAPON_FIRING_FREQUENCY);
41 | new cShotgun(this, Constants.DEFAULT_WEAPON_FIRING_FREQUENCY); // 9
42 |
43 | this.health = 50;
44 | healthText = new Text("", Scene.Assets.GetFont("pf_tempesta_seven"));
45 | healthText.Position = new Vector2f(pscene.AppController.MainWindow.DefaultView.Size.X - 500, 30);
46 | healthText.CharacterSize = 28; // in pixels, not points!
47 | healthText.FillColor = Color.White;
48 | healthText.Style = Text.Styles.Bold;
49 |
50 | this.boundingRadius = 12.0f;
51 | }
52 |
53 | protected override void initSprites()
54 | {
55 | base.initSprites();
56 |
57 | MyIntRect viewRect = Constants.CHAR_VIEW_RECT;
58 |
59 | spriteControl.AddAnimState(new cSpriteState(MotionType.STAND, HorizontalFacing.FACING_LEFT),
60 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
61 | Constants.CHAR_FRAME_WIDTH,
62 | Constants.CHAR_FRAME_HEIGHT,
63 | 0,
64 | 0,
65 | 0,
66 | 1,
67 | FRAME_TIME,
68 | viewRect);
69 |
70 | spriteControl.AddAnimState(new cSpriteState(MotionType.STAND, HorizontalFacing.FACING_RIGHT),
71 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
72 | Constants.CHAR_FRAME_WIDTH,
73 | Constants.CHAR_FRAME_HEIGHT,
74 | 0,
75 | 1,
76 | 0,
77 | 1,
78 | FRAME_TIME,
79 | viewRect);
80 |
81 | spriteControl.AddAnimState(new cSpriteState(MotionType.WALK, HorizontalFacing.FACING_LEFT),
82 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
83 | Constants.CHAR_FRAME_WIDTH,
84 | Constants.CHAR_FRAME_HEIGHT,
85 | 0,
86 | 0,
87 | 0, // 0
88 | 3, // 3
89 | 60, //FRAME_TIME,
90 | viewRect);
91 |
92 | spriteControl.AddAnimState(new cSpriteState(MotionType.WALK, HorizontalFacing.FACING_RIGHT),
93 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
94 | Constants.CHAR_FRAME_WIDTH,
95 | Constants.CHAR_FRAME_HEIGHT,
96 | 0,
97 | 1,
98 | 0, // 0
99 | 3, // 3
100 | 60, //FRAME_TIME,
101 | viewRect);
102 |
103 | spriteControl.AddAnimState(new cSpriteState(MotionType.JUMP, HorizontalFacing.FACING_LEFT),
104 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
105 | Constants.CHAR_FRAME_WIDTH,
106 | Constants.CHAR_FRAME_HEIGHT,
107 | 1,
108 | 0,
109 | 0,
110 | 1,
111 | FRAME_TIME,
112 | viewRect);
113 |
114 | spriteControl.AddAnimState(new cSpriteState(MotionType.JUMP, HorizontalFacing.FACING_RIGHT),
115 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
116 | Constants.CHAR_FRAME_WIDTH,
117 | Constants.CHAR_FRAME_HEIGHT,
118 | 1,
119 | 1,
120 | 0,
121 | 1,
122 | FRAME_TIME,
123 | viewRect);
124 |
125 |
126 | spriteControl.AddAnimState(new cSpriteState(MotionType.FALL, HorizontalFacing.FACING_LEFT),
127 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
128 | Constants.CHAR_FRAME_WIDTH,
129 | Constants.CHAR_FRAME_HEIGHT,
130 | 6,
131 | 0,
132 | 0,
133 | 1,
134 | FRAME_TIME,
135 | viewRect);
136 |
137 | spriteControl.AddAnimState(new cSpriteState(MotionType.FALL, HorizontalFacing.FACING_RIGHT),
138 | Scene.Assets.GetTexture(Constants.PLAYER_TEXTURE_NAME),
139 | Constants.CHAR_FRAME_WIDTH,
140 | Constants.CHAR_FRAME_HEIGHT,
141 | 6,
142 | 1,
143 | 0,
144 | 1,
145 | FRAME_TIME,
146 | viewRect);
147 | }
148 | protected override void init()
149 | {
150 | base.init();
151 | walkSpeed = Constants.PLAYER_WALK_SPEED;
152 | maxWalkSpeed = Constants.PLAYER_MAX_WALK_SPEED;
153 | }
154 |
155 | public override void Update(float step_time)
156 | {
157 | base.Update(step_time);
158 |
159 | }
160 |
161 | public override void Render(RenderTarget destination)
162 | {
163 |
164 | //viewPosition = cAppMath.Interpolate(position, lastPosition, alpha);
165 |
166 | p_followLight.Pos = GetCenterViewPos();
167 | fireLight.Pos = GetCenterViewPos();
168 |
169 | spriteControl.Render(destination, viewPosition);
170 | base.Render(destination);
171 | /*
172 | shape.Position = viewPosition; // - (viewSize / 2.0f);
173 | destination.Draw(shape);
174 | */
175 | healthText.DisplayedString = health.ToString();
176 | destination.Draw(healthText);
177 |
178 | }
179 |
180 | public void pickUp(cPickupInfo pickup)
181 | {
182 | pickup.applyEffect(this);
183 | }
184 |
185 |
186 | public void ItemAction(Vector2f mouse_pos)
187 | {
188 | if (weapon.Fire(mouse_pos))
189 | {
190 | //this.fireLight.TurnOn();
191 | return;
192 | }
193 | //this.fireLight.TurnOff();
194 | }
195 |
196 | public cWeapon CurrentWeapon
197 | {
198 | get { return weapon; }
199 | }
200 |
201 | ~cPlayer()
202 | {
203 | spriteControl.Clear();
204 | }
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/platformerGame/GameObjects/cTurret.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 | using platformerGame.GameObjects.PickupInfo;
11 | using platformerGame.Rendering;
12 | using platformerGame.App;
13 | using platformerGame.Inventory.Weapons;
14 |
15 | namespace platformerGame.GameObjects
16 | {
17 | class cTurret : cGameObject
18 | {
19 | // Sprite sprite;
20 | const double SPOT_DISTANCE = 300.0;
21 |
22 | cMachineGun gun;
23 | Vector2f gunFacingDirection;
24 |
25 | RectangleShape shape;
26 |
27 | cLight light;
28 |
29 | public cTurret() : base()
30 | {
31 |
32 | }
33 |
34 | public cTurret(GameScene scene, Vector2f pos) : base(scene, pos)
35 | {
36 | this.Bounds.SetDims(new Vector2f(16, 16));
37 | this.Bounds.SetPosByCenter(pos);
38 |
39 | gun = new cMachineGun(this, 6, "turret-bullet");
40 |
41 | gunFacingDirection = new Vector2f(0.0f, -1.0f);
42 |
43 | shape = new RectangleShape(new Vector2f(Bounds.dims.X, Bounds.dims.Y));
44 | shape.Origin = new Vector2f(Bounds.halfDims.X, Bounds.halfDims.Y);
45 | shape.FillColor = Color.Green;
46 | shape.Position = new Vector2f(pos.X, pos.Y);
47 | shape.Scale = new Vector2f(1.0f, 1.0f);
48 |
49 | light = new cLight();
50 | light.Pos = this.Bounds.center;
51 | light.Radius = 100.0f;
52 | light.LinearizeFactor = 0.8f;
53 | light.Bleed = 8.0f;
54 | light.Color = new Color(20, 184, 87);
55 | this.Scene.LightMap.AddStaticLight(light);
56 | }
57 |
58 | public override void Update(float step_time)
59 | {
60 | double dist = AppMath.Vec2Distance(Scene.Player.Bounds.center, this.Bounds.center);
61 | if(dist <= SPOT_DISTANCE)
62 | {
63 | Vector2f toTarget = AppMath.Vec2NormalizeReturn((Scene.Player.Bounds.center + Scene.Player.Velocity) - this.Bounds.center);
64 |
65 |
66 | float ang = AppMath.GetAngleBetwenVecs(toTarget, gunFacingDirection);
67 | Quaternion q = Quaternion.CreateFromAxisAngle(new Vector3f(toTarget.X, toTarget.Y, 0.0f), ang);
68 | Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3f(gunFacingDirection.X, gunFacingDirection.Y, 0.0f), ang);
69 | q = Quaternion.Slerp(q, q2, ang);
70 |
71 | gunFacingDirection = new Vector2f(q.X, q.Y); // toTarget;
72 | gun.Fire(Scene.Player.Bounds.center /*+ Scene.Player.Velocity * step_time*/);
73 | }
74 | }
75 |
76 | public override void Kill(cGameObject by)
77 | {
78 | Scene.LightMap.remove(this.light);
79 | }
80 |
81 | public override bool isActive()
82 | {
83 | return base.isActive();
84 | }
85 |
86 | public override void Render(RenderTarget destination)
87 | {
88 | destination.Draw(shape, new RenderStates(BlendMode.Add));
89 |
90 | DrawingBase.DrawLine(destination, this.Bounds.center, this.Bounds.center + gunFacingDirection * 40.0f, Color.Yellow, BlendMode.Alpha);
91 | // DrawingBase.DrawRectangleShape(destination, this.Bounds, new Color(240,140,160), BlendMode.Alpha);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/platformerGame/GlobalClock.cs:
--------------------------------------------------------------------------------
1 | using platformerGame.Utilities;
2 |
3 | namespace platformerGame
4 | {
5 | public class GlobalClock
6 | {
7 | /*private static readonly GlobalClock instance = new GlobalClock();*/
8 |
9 | private static AppTimer timer;
10 | /*private GlobalClock() { }*/
11 | static GlobalClock()
12 | {
13 | timer = new AppTimer();
14 | }
15 | /*
16 | public static GlobalClock Instance
17 | {
18 | get
19 | {
20 | return instance;
21 | }
22 | }
23 | */
24 | public static void Start()
25 | {
26 |
27 | timer.Start();
28 | }
29 |
30 | public static double GetCurrentTime()
31 | {
32 | return timer.GetCurrentTime();
33 | }
34 |
35 | public static double GetTimeInMilliseconds()
36 | {
37 | return timer.GetCurrentTimeAsMilliseconds();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/platformerGame/IDrawable.cs:
--------------------------------------------------------------------------------
1 | using SFML.Graphics;
2 |
3 | namespace platformerGame
4 | {
5 | public interface IDrawable
6 | {
7 | //bool IsVisibleOnScreen();
8 | void CalculateViewPos(float alpha);
9 | void Render(RenderTarget destination);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/platformerGame/IGame.cs:
--------------------------------------------------------------------------------
1 | using SFML.Graphics;
2 | using SFML.Window;
3 |
4 | namespace OverlordEngine
5 | {
6 | /*
7 | delegate void BeforeUpdateEvent();
8 | delegate void UpdateEvent(float stepTime);
9 | delegate void PreRenderEvent(float alpha);
10 | delegate void RenderEvent(RenderTarget target);
11 | */
12 |
13 | interface IGame
14 | {
15 | void Init();
16 | void Destroy();
17 | void OnSingleMouseClick(MouseButtonEventArgs e);
18 | void OnKeyPressed(KeyEventArgs e);
19 | void OnBeforeUpdate();
20 | void OnUpdateFixed(float stepTime);
21 | void OnUpdateVariable(float stepTime = 1.0f);
22 | void OnPreRender(float alpha);
23 | void OnRender(RenderTarget target);
24 | }
25 |
26 | class PlatformerGame : IGame
27 | {
28 | public PlatformerGame()
29 | {
30 | }
31 |
32 |
33 | public void OnBeforeUpdate()
34 | {
35 |
36 | }
37 |
38 | public void OnPreRender(float alpha)
39 | {
40 |
41 | }
42 |
43 | public void OnRender(RenderTarget target)
44 | {
45 |
46 | }
47 |
48 | public void OnUpdateFixed(float stepTime)
49 | {
50 |
51 | }
52 |
53 | public void OnUpdateVariable(float stepTime = 1.0f)
54 | {
55 |
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/platformerGame/Inventory/Weapons/cMachineGun.cs:
--------------------------------------------------------------------------------
1 | using SFML.System;
2 | using platformerGame.GameObjects;
3 | using platformerGame.Utilities;
4 | using platformerGame.Particles;
5 |
6 | namespace platformerGame.Inventory.Weapons
7 | {
8 | class cMachineGun : cWeapon
9 | {
10 |
11 | public cMachineGun(cGameObject owner, int firing_frequency, string bullet_breed_id = "simple-bullet")
12 | : base(owner, firing_frequency, bullet_breed_id)
13 | {
14 | this.maxAmmo = 300;
15 | this.currentAmmo = maxAmmo;
16 | this.magazineCapacity = 30;
17 | this.timeToReload = 1.5f;
18 | this.spread = (float)AppMath.DegressToRadian(4);
19 | this.bulletsPerShot = 1;
20 | }
21 |
22 | public override bool Fire(Vector2f target)
23 | {
24 | if (this.isReadForNextShot())
25 | {
26 | Vector2f dir = AppMath.Vec2NormalizeReturn(target - owner.Bounds.center);
27 | Vector2f toSpreadTarget = AppMath.GetRandomVecBySpread(dir, spread);
28 |
29 |
30 | this.Shot(toSpreadTarget);
31 | decreaseAmmo();
32 |
33 |
34 | owner.Scene.Assets.PlaySound("cg1", 2);
35 |
36 | /*
37 | this.owner.Scene.QueueAction(() =>
38 | {
39 | var e = this.owner.Scene.ParticleManager["explosions"] as cExplosionController;
40 | e.Line(new EmissionInfo(this.owner.Bounds.center, toSpreadTarget));
41 |
42 | });
43 | */
44 | }
45 |
46 | return false;
47 |
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/platformerGame/Inventory/Weapons/cShotgun.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using SFML.System;
4 |
5 | using platformerGame.Utilities;
6 | using platformerGame.GameObjects;
7 |
8 | namespace platformerGame.Inventory.Weapons
9 | {
10 | class cShotgun : cWeapon
11 | {
12 |
13 | public cShotgun(cGameObject owner, int firing_frequency, string bullet_breed_id = "simple-bullet")
14 | : base(owner, firing_frequency, bullet_breed_id)
15 | {
16 | this.spread = (float)AppMath.DegressToRadian(3);
17 | this.bulletsPerShot = 4;
18 | }
19 |
20 | public override bool Fire(Vector2f target)
21 | {
22 | if (this.isReadForNextShot())
23 | {
24 | Vector2f dir = AppMath.Vec2NormalizeReturn(target - owner.Bounds.center);
25 | float dirAngle = (float)AppMath.GetAngleOfVector(dir);
26 | float unitAngle = spread / bulletsPerShot;
27 | float tangle = dirAngle - ((bulletsPerShot / 2.0f) * unitAngle);
28 | for (int i = 0; i < bulletsPerShot; ++i)
29 | {
30 | tangle += i * unitAngle;
31 | //Vector2f toSpreadTarget = cAppMath.GetRandomVecBySpread(dir, spread);
32 | Vector2f toSpreadTarget = new Vector2f((float)Math.Cos(tangle), (float)Math.Sin(tangle));
33 |
34 | this.Shot(toSpreadTarget);
35 | }
36 |
37 | owner.Scene.Assets.PlaySound("shotgun", 3);
38 |
39 | return true;
40 |
41 | }
42 |
43 | return false;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/platformerGame/Inventory/Weapons/cWeapon.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.System;
8 | using platformerGame.GameObjects;
9 |
10 | using platformerGame.Utilities;
11 |
12 | namespace platformerGame.Inventory.Weapons
13 | {
14 | // TODO: make inherited from Inventory.cItem
15 | abstract class cWeapon
16 | {
17 | protected cGameObject owner;
18 | protected cRegulator regulator;
19 | protected int firingFrequency;
20 | protected float spread; // in radian
21 |
22 | protected int currentAmmo;
23 | protected int maxAmmo;
24 | protected int magazineCapacity;
25 | protected int bulletsPerShot;
26 | protected float timeToReload;
27 |
28 | protected string bulletBreedID;
29 |
30 | public cWeapon(cGameObject owner, int firing_frequency, string bullet_breed_id)
31 | {
32 | this.owner = owner;
33 | this.firingFrequency = firing_frequency;
34 | this.regulator = new cRegulator();
35 | this.regulator.resetByFrequency(firing_frequency);
36 | this.spread = (float)AppMath.DegressToRadian(2);
37 | this.bulletsPerShot = 1;
38 | this.bulletBreedID = bullet_breed_id;
39 | }
40 |
41 | protected bool isReadForNextShot()
42 | {
43 | return regulator.isReady();
44 | }
45 |
46 | public abstract bool Fire(Vector2f target);
47 | /*
48 | {
49 | if(this.isReadForNextShot())
50 | {
51 | Vector2f dir = AppMath.Vec2NormalizeReturn(target - owner.Bounds.center);
52 | Vector2f toSpreadTarget = AppMath.GetRandomVecBySpread(dir, spread);
53 | cBullet b = new cBullet(this.owner, owner.Bounds.center, toSpreadTarget);
54 | owner.Scene.EntityPool.AddBullet(b);
55 | }
56 | }
57 | */
58 |
59 | // in every weapon, the same method used to add a bullet to the scene
60 | protected void Shot(Vector2f direction)
61 | {
62 | cBullet b = new cBullet(this.owner, BulletBreed.GetBreed(this.bulletBreedID), owner.Bounds.center, direction);
63 | owner.Scene.EntityPool.AddBullet(b);
64 | }
65 |
66 | protected void decreaseAmmo()
67 | {
68 | this.currentAmmo -= bulletsPerShot;
69 | }
70 |
71 | public int CurrentAmmo
72 | {
73 | get { return this.currentAmmo; }
74 | }
75 |
76 | public int MaxAmmo
77 | {
78 | get { return this.maxAmmo; }
79 | }
80 |
81 | public int FiringFrequency
82 | {
83 | get {return firingFrequency; }
84 | set { firingFrequency = value; }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/platformerGame/Inventory/cInventory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using platformerGame.GameObjects;
8 |
9 | namespace platformerGame.Inventory
10 | {
11 | class cInventory
12 | {
13 | Dictionary items;
14 |
15 | cGameObject owner;
16 | cItem currentItem = null;
17 |
18 | public cInventory()
19 | {
20 | this.items = new Dictionary();
21 | }
22 |
23 |
24 | public void AddItem(string name, cItem item)
25 | {
26 | if(this.items.ContainsKey(name))
27 | {
28 | this.items[name].HandleAlreadyHave(item);
29 | return;
30 | }
31 |
32 | this.items.Add(name, item);
33 | }
34 |
35 | public void Delete(string name)
36 | {
37 | this.items.Remove(name);
38 | }
39 |
40 | public bool Switch(string to_name)
41 | {
42 | if (this.items.ContainsKey(to_name))
43 | {
44 | currentItem = items[to_name];
45 | return true;
46 | }
47 |
48 | return false;
49 | }
50 |
51 | public void Use()
52 | {
53 | currentItem.Use();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/platformerGame/Inventory/cItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Inventory
8 | {
9 | abstract class cItem
10 | {
11 | protected cInventory inventory;
12 |
13 | public cItem(cInventory invetory)
14 | {
15 | this.inventory = inventory;
16 | }
17 |
18 | public abstract void Use();
19 | public abstract void HandleAlreadyHave(cItem item);
20 |
21 | public cInventory Inventory
22 | {
23 | get { return this.inventory; }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/platformerGame/Map/cTile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 |
9 | namespace platformerGame.Map
10 | {
11 | enum TileType
12 | {
13 | EMPTY = 0, //Üres - járható
14 | WALL = 1, //Fal - nem járható
15 | ONEWAY_PLATFORM = 2, //"Leugrós" platform
16 | WATER = 3, //Víz
17 | SPIKE = 4 //Tüske
18 | }
19 | class cTile
20 | {
21 | ///
22 | /// Egyedi azonosító
23 | ///
24 | public int IdCode { get; set; }
25 |
26 | public int GlobalId { get; set; }
27 | ///
28 | /// Minden tile-nak van típusa
29 | ///
30 | public TileType Type { get; set; }
31 |
32 | public AABB PosOnTexture { get; set; }
33 | public bool PlayerCollidable { get; set; }
34 |
35 | public bool IsCheckedWater { get; set; }
36 |
37 | public cTile()
38 | {
39 | IdCode = 0;
40 | GlobalId = -1;
41 | Type = TileType.EMPTY;
42 | PlayerCollidable = false;
43 | PosOnTexture = new AABB(0, 0, 1, 1);
44 | IsCheckedWater = false;
45 | }
46 | public cTile(int id_code, TileType type)
47 | {
48 | this.IdCode = id_code;
49 | this.Type = type;
50 | GlobalId = -1;
51 | PlayerCollidable = false;
52 | PosOnTexture = new AABB(0, 0, 1, 1);
53 | IsCheckedWater = false;
54 |
55 | }
56 |
57 | public cTile(cTile other)
58 | {
59 | this.IdCode = other.IdCode;
60 | this.Type = other.Type;
61 | }
62 |
63 | public cTile ShallowCopy()
64 | {
65 | return (cTile)this.MemberwiseClone();
66 | }
67 | public bool IsWalkAble()
68 | {
69 | return (Type != TileType.WALL);
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/platformerGame/Map/cTileLayer.cs:
--------------------------------------------------------------------------------
1 | using SFML.Graphics;
2 | using SFML.System;
3 | using System.Collections.Generic;
4 |
5 | namespace platformerGame.Map
6 | {
7 | class cTileLayer
8 | {
9 | // TileLayerType
10 | int typeID;
11 |
12 | VertexArray vertices;
13 |
14 | RenderStates renderStates;
15 |
16 | public cTileLayer(int type_id, Texture tile_set)
17 | {
18 | this.typeID = type_id;
19 | this.vertices = new VertexArray(PrimitiveType.Quads);
20 | this.renderStates = new RenderStates(BlendMode.Alpha);
21 | this.renderStates.Texture = tile_set;
22 | }
23 |
24 | public void ClearVertexArray()
25 | {
26 | this.vertices.Clear();
27 | }
28 |
29 | public void AddTileVertices(AABB tile_region, AABB pos_in_tileset)
30 | {
31 | vertices.Append(new Vertex(new Vector2f(tile_region.topLeft.X, tile_region.topLeft.Y), Color.White, new Vector2f(pos_in_tileset.topLeft.X, pos_in_tileset.topLeft.Y)));
32 | vertices.Append(new Vertex(new Vector2f(tile_region.getTopRight().X, tile_region.getTopRight().Y), Color.White, new Vector2f(pos_in_tileset.getTopRight().X, pos_in_tileset.getTopRight().Y)));
33 | vertices.Append(new Vertex(new Vector2f(tile_region.rightBottom.X, tile_region.rightBottom.Y), Color.White, new Vector2f(pos_in_tileset.rightBottom.X, pos_in_tileset.rightBottom.Y)));
34 | vertices.Append(new Vertex(new Vector2f(tile_region.getLeftBottom().X, tile_region.getLeftBottom().Y), Color.White, new Vector2f(pos_in_tileset.getLeftBottom().X, pos_in_tileset.getLeftBottom().Y)));
35 | }
36 |
37 | public void Draw(RenderTarget destination)
38 | {
39 | destination.Draw(vertices, renderStates);
40 | }
41 |
42 | public int TypeID
43 | {
44 | get { return typeID; }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/platformerGame/Map/cTileMapRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 |
11 | namespace platformerGame.Map
12 | {
13 | class cTileMapRenderer
14 | {
15 | cWorld world;
16 |
17 | List drawTileLayers;
18 |
19 | AABB drawTileBounds;
20 |
21 | Texture tileSetTexture;
22 |
23 | public cTileMapRenderer(cWorld world)
24 | {
25 | this.world = world;
26 | this.drawTileLayers = new List();
27 |
28 | this.tileSetTexture = world.CurrentLevel.TilesetTexture;
29 |
30 | drawTileBounds = new AABB();
31 |
32 | this.setupLayers();
33 |
34 | // textureOfTiles = new RenderTexture((uint)m_WorldBounds.dims.X, (uint)m_WorldBounds.dims.Y); //(windowSize.X, windowSize.Y);
35 | // textureOfTiles.SetActive(true);
36 |
37 | }
38 |
39 | private void setupLayers()
40 | {
41 | drawTileLayers.Add(new cTileLayer(TileLayerTypes.BACKGROUND_1, tileSetTexture));
42 | drawTileLayers.Add(new cTileLayer(TileLayerTypes.BACKGROUND_2, tileSetTexture));
43 | drawTileLayers.Add(new cTileLayer(TileLayerTypes.WALLS, tileSetTexture));
44 | }
45 |
46 | public void ClearTileLayers()
47 | {
48 | foreach (var layer in drawTileLayers)
49 | {
50 | layer.ClearVertexArray();
51 | }
52 | }
53 |
54 | ///
55 | /// Filters the visible tiles and build the vertex arrays of each layer
56 | ///
57 | private void filterDrawableTiles()
58 | {
59 | int startTileX = (int)drawTileBounds.topLeft.X;
60 | int startTileY = (int)drawTileBounds.topLeft.Y;
61 | int endTileX = (int)drawTileBounds.rightBottom.X;
62 | int endTileY = (int)drawTileBounds.rightBottom.Y;
63 |
64 | // important to call !!
65 | this.ClearTileLayers();
66 |
67 |
68 | Vector2f drawPos = new Vector2f();
69 |
70 | const int spaceOffset = 0;
71 |
72 | for (int y = startTileY; y < endTileY; y++)
73 | {
74 | for (int x = startTileX; x < endTileX; x++)
75 | {
76 | for (int layer = 0; layer < drawTileLayers.Count; layer++)
77 | {
78 | cTile tempTile = world.CurrentLevel.GetTileAtXY(x, y, drawTileLayers[layer].TypeID);
79 |
80 | if (tempTile.Type != TileType.EMPTY)
81 | {
82 | // tilesToDraw.Add(new DrawTile(x, y, tempTile.PosOnTexture));
83 |
84 | drawPos.X = (world.WorldBounds.topLeft.X + x * Constants.TILE_SIZE) + spaceOffset;
85 | drawPos.Y = (world.WorldBounds.topLeft.Y + y * Constants.TILE_SIZE) + spaceOffset;
86 |
87 | AABB tileBounds = world.getAABBFromWorldPos(drawPos);
88 |
89 | drawTileLayers[layer].AddTileVertices(tileBounds, tempTile.PosOnTexture);
90 | }
91 | }
92 | }
93 | }
94 |
95 | }
96 |
97 | public void RecalculateDrawBounds(AABB viewRect)
98 | {
99 | drawTileBounds = viewRect.ShallowCopy();
100 |
101 | drawTileBounds.topLeft.X = (float)Math.Floor((drawTileBounds.topLeft.X / Constants.TILE_SIZE) - 1);
102 | drawTileBounds.topLeft.Y = (float)Math.Floor((drawTileBounds.topLeft.Y / Constants.TILE_SIZE) - 1);
103 |
104 | drawTileBounds.rightBottom.X = (float)Math.Ceiling((drawTileBounds.rightBottom.X / Constants.TILE_SIZE) + 1);
105 | drawTileBounds.rightBottom.Y = (float)Math.Ceiling((drawTileBounds.rightBottom.Y / Constants.TILE_SIZE) + 1);
106 |
107 | // TODO comment
108 | drawTileBounds.topLeft.X = Math.Max(drawTileBounds.topLeft.X, 0.0f);
109 | drawTileBounds.topLeft.Y = Math.Max(drawTileBounds.topLeft.Y, 0.0f);
110 | drawTileBounds.rightBottom.X = Math.Min(drawTileBounds.rightBottom.X, this.world.CurrentLevel.Width);
111 | drawTileBounds.rightBottom.Y = Math.Min(drawTileBounds.rightBottom.Y, this.world.CurrentLevel.Height);
112 |
113 | filterDrawableTiles();
114 |
115 | }
116 | public void Render(RenderTarget destination, AABB view_rect = null)
117 | {
118 | foreach (var layer in drawTileLayers)
119 | {
120 | layer.Draw(destination);
121 | }
122 |
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/platformerGame/MapCollider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame
8 | {
9 | class MapCollider
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/platformerGame/Particles/EmissionInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.System;
8 |
9 | namespace platformerGame.Particles
10 | {
11 | class EmissionInfo
12 | {
13 | Particle particleRef;
14 | Vector2f startPosition;
15 | Vector2f emitDirection;
16 | float speed; // should be normalized
17 |
18 | public Particle Particle
19 | {
20 | get { return particleRef; }
21 | set { particleRef = value; }
22 | }
23 |
24 | public Vector2f StartPosition
25 | {
26 | get { return startPosition; }
27 | set { startPosition = value; }
28 | }
29 |
30 | public Vector2f EmitDirection
31 | {
32 | get { return emitDirection; }
33 | set { emitDirection = value; }
34 | }
35 |
36 | public float Speed
37 | {
38 | get { return this.speed; }
39 | }
40 |
41 | public EmissionInfo(Vector2f start_position)
42 | {
43 | this.particleRef = null;
44 | this.startPosition = start_position;
45 | this.emitDirection = new Vector2f(0.0f, 0.0f);
46 | this.speed = 0.0f;
47 | }
48 |
49 | public EmissionInfo(Vector2f start_position, Vector2f emit_direction, float speed = 0.0f)
50 | {
51 | this.particleRef = null;
52 | this.startPosition = start_position;
53 | this.emitDirection = emit_direction;
54 | this.speed = speed;
55 | }
56 |
57 | public EmissionInfo(Particle particle, Vector2f start_position)
58 | {
59 | this.particleRef = particle;
60 | this.startPosition = start_position;
61 | this.emitDirection = new Vector2f(0.0f, 0.0f);
62 | this.speed = 0.0f;
63 | }
64 |
65 | public EmissionInfo(Particle particle, Vector2f start_position, Vector2f emit_direction, float speed = 0.0f)
66 | {
67 | this.particleRef = particle;
68 | this.startPosition = start_position;
69 | this.emitDirection = emit_direction;
70 | this.speed = speed;
71 | }
72 |
73 | public bool hasSpeed()
74 | {
75 | return speed > 0.0f;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/platformerGame/Particles/IParticleContainer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Particles
8 | {
9 | interface IParticleContainer
10 | {
11 | Particle getNew();
12 | Particle get(uint index);
13 | void activate(uint index);
14 | void deactivate(uint index);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/platformerGame/Particles/Particle.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.System;
8 | using SFML.Graphics;
9 |
10 | namespace platformerGame
11 | {
12 | class Particle
13 | {
14 | public Vector2f Pos;
15 | public Vector2f LastPos;
16 | public Vector2f ViewPos;
17 | public Vector2f StartPos;
18 |
19 | public Vector2f Dims; //width, height
20 | public Vector2f Vel; // velocity
21 | public Vector2f Heading;
22 |
23 | public Color Color;
24 | public float SlowDown;
25 | public float MaxSpeed;
26 | public float ScaleSpeed;
27 | public float Opacity;
28 | public float Fade;
29 | public float Life;
30 | public float Scale;
31 |
32 | public float Rotation; // in radian
33 |
34 | public bool Intersects;
35 |
36 | /*
37 | * UpdateController updater;
38 | *
39 | */
40 |
41 | public Particle()
42 | {
43 | Pos = new Vector2f(0.0f, 0.0f);
44 | LastPos = new Vector2f(0.0f, 0.0f);
45 | ViewPos = new Vector2f(0.0f, 0.0f);
46 | StartPos = new Vector2f(0.0f, 0.0f);
47 | Dims = new Vector2f(2.0f, 2.0f); // 2x2 square
48 | Vel = new Vector2f(0.0f, 0.0f);
49 | Heading = new Vector2f(0.0f, 0.0f);
50 | Color = new Color(255, 255, 255, 255);
51 | SlowDown = 0.789f;
52 | MaxSpeed = 200.0f;
53 | ScaleSpeed = 0.0f;
54 | Opacity = 255.0f;
55 | Fade = 255.0f;
56 | Life = 1.0f;
57 | Rotation = 0.0f;
58 | Scale = 1.0f;
59 | Intersects = false;
60 | }
61 |
62 | public AABB getBoundingBox()
63 | {
64 | AABB b = new AABB();
65 | b.SetDims(Dims);
66 | b.SetPosByCenter(Pos);
67 | return b;
68 | }
69 |
70 | public Particle(Particle p)
71 | {
72 | this.Pos = p.Pos;
73 | this.LastPos = p.LastPos;
74 | this.ViewPos = p.ViewPos;
75 | this.StartPos = p.StartPos;
76 | this.Dims = p.Dims;
77 | this.Vel = p.Vel;
78 | this.Heading = p.Heading;
79 | this.Color = new Color(p.Color);
80 | this.SlowDown = p.SlowDown;
81 | this.MaxSpeed = p.MaxSpeed;
82 | this.ScaleSpeed = p.ScaleSpeed;
83 | this.Opacity = p.Opacity;
84 | this.Fade = p.Fade;
85 | this.Life = p.Life;
86 | this.Rotation = p.Rotation;
87 | this.Scale = p.Scale;
88 | this.Intersects = p.Intersects;
89 | }
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/platformerGame/Particles/cBaseParticleController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 |
8 | using SFML.System;
9 | using SFML.Graphics;
10 |
11 | namespace platformerGame.Particles
12 | {
13 | abstract class cBaseParticleController
14 | {
15 | protected cParticleManager particleManager;
16 | protected cParticlePool pool;
17 | protected VertexArray vertices;
18 | protected RenderStates renderStates;
19 |
20 | public cBaseParticleController(cParticleManager manager, int max_particles = 300)
21 | {
22 | this.particleManager = manager;
23 | this.pool = new cParticlePool(max_particles); // new ParticlePoolList()
24 | this.vertices = new VertexArray(PrimitiveType.Quads);
25 | this.renderStates = new RenderStates(BlendMode.Add);
26 | }
27 |
28 | protected void loopAddition(EmissionInfo emission, uint num_particles)
29 | {
30 | uint i = 0;
31 | while ((emission.Particle = pool.getNew()) != null && i < num_particles)
32 | {
33 | initParticle(emission);
34 | ++i;
35 | }
36 | }
37 |
38 | public int NumActive
39 | {
40 | get { return (int)pool.CountActive; }
41 | }
42 |
43 | protected abstract void initParticle(EmissionInfo emission);
44 |
45 | public abstract void Update(float step_time);
46 |
47 | public abstract void BuildVertexBuffer(float alpha);
48 |
49 | public abstract void Render(RenderTarget destination, float alpha);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/platformerGame/Particles/cFireworksController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Diagnostics;
7 |
8 | using SFML.System;
9 | using SFML.Graphics;
10 |
11 | using platformerGame.Utilities;
12 |
13 | namespace platformerGame.Particles
14 | {
15 | class cFireworksController : cBaseParticleController
16 | {
17 | double minScale = 0.3;
18 | double maxScale = 0.6;
19 |
20 | public cFireworksController(cParticleManager manager, int max_particles = 300) : base(manager, max_particles)
21 | {
22 | this.renderStates.Texture = manager.FireworksTexture;
23 | }
24 |
25 |
26 | protected override void initParticle(EmissionInfo emission)
27 | {
28 | Particle particle = emission.Particle;
29 |
30 | particle.Pos = emission.StartPosition;
31 | particle.LastPos = particle.Pos;
32 | particle.ViewPos = particle.Pos;
33 | particle.MaxSpeed = AppMath.GetRandomNumber(600, 800); //200,400 | 700, 900 | (400, 600); //3, 8//Math->GetRandomNumber(510, 800); // 2000.0f
34 |
35 | //------------------------------------------------------------------------------------------------
36 | float angle = (float)AppMath.DegressToRadian(AppMath.GetRandomNumber(0, 360));//sDivisions * m_Angles;
37 |
38 | particle.Vel = new Vector2f((float)Math.Cos(angle) * particle.MaxSpeed, (float)Math.Sin(angle) * particle.MaxSpeed);
39 | //------------------------------------------------------------------------------------------------
40 | //------------------------------------------------------------------------------------------------
41 |
42 | //particle.m_Vel = sf::Vector2f(Math->GetRandomClamped() * particle.m_MaxSpeed, Math->GetRandomClamped() *particle.m_MaxSpeed);
43 | particle.SlowDown = 0.98f; //0.92f;
44 | //particle.m_SlowDown = (float)Math->GetRandomDoubleInRange(0.55, 0.7); //0.6f;
45 | //phs->AddForce( sf::Vector2f(Math->GetRandomClamped() * phs->MaxSpeed, Math->GetRandomClamped() * phs->MaxSpeed) );
46 |
47 | Vector2u uSize = this.renderStates.Texture.Size;
48 |
49 | particle.Scale = (float)AppMath.GetRandomDoubleInRange(this.minScale, this.maxScale);
50 |
51 | particle.Dims = new Vector2f(uSize.X * particle.Scale, uSize.Y * particle.Scale);
52 |
53 | particle.ScaleSpeed = -AppMath.GetRandomNumber(10, 50);
54 | particle.Color = Utils.GetRandomRedColor();
55 | particle.Opacity = 255.0f;
56 | particle.Life = 1.0f;
57 | particle.Fade = 60; //Math->GetRandomNumber(100, 240);
58 |
59 | particle.Intersects = false;
60 | }
61 |
62 | public void LittleExplosion(EmissionInfo emission)
63 | {
64 | minScale = 0.2;
65 | maxScale = 0.4;
66 | loopAddition(emission, 3);
67 | }
68 |
69 | public void NormalExplosion(EmissionInfo emission)
70 | {
71 | minScale = 0.5;
72 | maxScale = 0.8;
73 | loopAddition(emission, 20);
74 | }
75 |
76 | public override void Update(float step_time)
77 | {
78 | cWorld world = particleManager.Scene.World;
79 |
80 | for (int i = 0; i < pool.CountActive; ++i)
81 | {
82 | Particle p = pool.get(i);
83 |
84 | if (!p.Intersects)
85 | {
86 |
87 | /*
88 | p.Dims.Y += p.ScaleSpeed * step_time; //+=
89 | p.Dims.y += p.ScaleSpeed * step_time; //+=
90 | */
91 | AppMath.Vec2Truncate(ref p.Vel, p.MaxSpeed * 1.5f);
92 |
93 |
94 | p.Vel.Y += (Constants.GRAVITY * 40.0f * (step_time * step_time));
95 |
96 | p.Vel.X *= p.SlowDown;
97 | p.Vel.Y *= p.SlowDown;
98 |
99 | //p.Heading = cAppMath.Vec2NormalizeReturn(p.Vel);
100 | p.LastPos = p.Pos;
101 | p.Pos.X += p.Vel.X * step_time;
102 | p.Pos.Y += p.Vel.Y * step_time;
103 |
104 |
105 |
106 | if (!AppMath.Vec2IsZero(p.Vel))
107 | {
108 | p.Heading = AppMath.Vec2NormalizeReturn(p.Vel);
109 | p.Rotation = (float)AppMath.GetAngleOfVector(p.Heading);
110 | }
111 |
112 | world.collideParticleRayTrace(p, step_time);
113 |
114 |
115 | }
116 |
117 | p.Opacity -= p.Fade * step_time;
118 |
119 | if (p.Opacity <= 0.0f)
120 | {
121 | p.Opacity = 0.0f;
122 |
123 | pool.deactivate(i);
124 |
125 | }
126 |
127 | p.Color.A = (byte)p.Opacity;
128 | }
129 | }
130 |
131 | public override void BuildVertexBuffer(float alpha)
132 | {
133 | uint multiplier = 4;
134 | uint vNum = ((uint)pool.CountActive * multiplier) + 1;
135 |
136 | //vertices.Clear();
137 | vertices.Resize(vNum);
138 |
139 | float division = 2.0f;
140 |
141 | Vector2u uSize = this.renderStates.Texture.Size;
142 | float tSizeX = uSize.X;
143 | float tSizeY = uSize.Y;
144 |
145 | Vector2f newDims = new Vector2f();
146 |
147 | for (int i = 0; i < pool.CountActive; ++i)
148 | {
149 | Particle p = pool.get(i);
150 |
151 | newDims.X = p.Dims.X / division;
152 | newDims.Y = p.Dims.Y / division;
153 |
154 | p.ViewPos = AppMath.Interpolate(p.Pos, p.LastPos, alpha);
155 |
156 | uint vertexIndex = (uint)i * multiplier;
157 |
158 | Vector2f v0Pos = new Vector2f(p.ViewPos.X - newDims.X,
159 | p.ViewPos.Y - newDims.Y);
160 |
161 | Vector2f v1Pos = new Vector2f(p.ViewPos.X + newDims.X,
162 | p.ViewPos.Y - newDims.Y);
163 |
164 | Vector2f v2Pos = new Vector2f(p.ViewPos.X + newDims.X,
165 | p.ViewPos.Y + newDims.Y);
166 |
167 | Vector2f v3Pos = new Vector2f(p.ViewPos.X - newDims.X,
168 | p.ViewPos.Y + newDims.Y);
169 |
170 |
171 | // if want rotation included:
172 | Transform rot = Transform.Identity;
173 | rot.Rotate((float)AppMath.RadianToDegress(p.Rotation), p.ViewPos);
174 |
175 | v0Pos = rot.TransformPoint(v0Pos);
176 | v1Pos = rot.TransformPoint(v1Pos);
177 | v2Pos = rot.TransformPoint(v2Pos);
178 | v3Pos = rot.TransformPoint(v3Pos);
179 | // END of rotation code
180 |
181 | // Top-left
182 | Vertex v0 = new Vertex(
183 | v0Pos,
184 | p.Color,
185 | new Vector2f(0.0f, 0.0f)
186 | );
187 |
188 | // Top-right
189 | Vertex v1 = new Vertex(
190 | v1Pos,
191 | p.Color,
192 | new Vector2f(tSizeX, 0.0f)
193 | );
194 |
195 | // Bottom-right
196 | Vertex v2 = new Vertex(
197 | v2Pos,
198 | p.Color,
199 | new Vector2f(tSizeX, tSizeY)
200 | );
201 |
202 | //Bottom-left
203 | Vertex v3 = new Vertex(
204 | v3Pos,
205 | p.Color,
206 | new Vector2f(0.0f, tSizeY)
207 | );
208 |
209 | vertices[vertexIndex + 0] = v0;
210 | vertices[vertexIndex + 1] = v1;
211 | vertices[vertexIndex + 2] = v2;
212 | vertices[vertexIndex + 3] = v3;
213 | }
214 | }
215 |
216 | public override void Render(RenderTarget destination, float alpha)
217 | {
218 | destination.Draw(vertices, renderStates);
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/platformerGame/Particles/cParticleManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.App;
10 |
11 | namespace platformerGame.Particles
12 | {
13 |
14 | ///
15 | /// This class attempts to handle particle effects effictively by using different controllers, which are
16 | /// operate on the particles stored in the particle pool.
17 | ///
18 | class cParticleManager
19 | {
20 | GameScene sceneRef;
21 |
22 | readonly Texture explosionTexture;
23 | readonly Texture fireworksTexture;
24 | readonly Texture smokeTexture;
25 |
26 | Dictionary systems;
27 |
28 | Text label;
29 |
30 | public cParticleManager(GameScene scene)
31 | {
32 | this.sceneRef = scene;
33 | this.systems = new Dictionary();
34 |
35 | // must be called before controller additions
36 | explosionTexture = scene.Assets.GetTexture("simple_particle"); //simple_particle
37 | fireworksTexture = scene.Assets.GetTexture("bullet3");
38 | smokeTexture = scene.Assets.GetTexture("smoke_particle");
39 |
40 | this.systems.Add("explosions", new cExplosionController(this));
41 | this.systems.Add("fireworks", new cFireworksController(this));
42 | this.systems.Add("sprays", new cSprayController(this));
43 |
44 | label = new Text();
45 | label.Position = new Vector2f(20, 45);
46 |
47 | label.Font = scene.Assets.GetFont("BGOTHL");
48 | label.CharacterSize = 24;
49 | label.FillColor = Color.White;
50 | label.Style = Text.Styles.Bold;
51 |
52 | }
53 |
54 | public void Update(float step_time)
55 | {
56 | foreach (var item in systems)
57 | {
58 | cBaseParticleController c = item.Value;
59 | c.Update(step_time);
60 | }
61 | }
62 |
63 | public void PreRender(float alpha)
64 | {
65 | // if we want calculate viewPos before all renderings are started...
66 | foreach (var item in systems)
67 | {
68 | cBaseParticleController c = item.Value;
69 | c.BuildVertexBuffer(alpha);
70 | }
71 | }
72 |
73 | public void Render(RenderTarget destination, float alpha)
74 | {
75 | //label.DisplayedString = "Active explosion particles: " + explosions.NumActive.ToString();
76 | //destination.Draw(label);
77 | foreach (var item in systems)
78 | {
79 | cBaseParticleController c = item.Value;
80 | c.Render(destination, alpha);
81 | }
82 | }
83 |
84 | public Texture ExplosionTexture
85 | {
86 | get { return explosionTexture; }
87 | }
88 |
89 | public Texture FireworksTexture
90 | {
91 | get { return fireworksTexture; }
92 | }
93 |
94 | public Texture SmokeTexture
95 | {
96 | get { return smokeTexture; }
97 | }
98 |
99 | public GameScene Scene
100 | {
101 | get { return sceneRef; }
102 | }
103 |
104 | public cBaseParticleController this[string key]
105 | {
106 | get
107 | {
108 | cBaseParticleController s;
109 | return this.systems.TryGetValue(key, out s) ? s : null;
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/platformerGame/Particles/cParticlePool.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.System;
8 | using SFML.Graphics;
9 |
10 | namespace platformerGame.Particles
11 | {
12 | ///
13 | /// Simple class storing the particles.
14 | ///
15 | class cParticlePool
16 | {
17 | int capacity;
18 | Particle[] particles;
19 | int countActive;
20 |
21 | public cParticlePool()
22 | {
23 | capacity = 10;
24 | initParticles();
25 | countActive = 0;
26 | }
27 |
28 | public cParticlePool(int capacity)
29 | {
30 | this.capacity = capacity;
31 | initParticles();
32 | countActive = 0;
33 | }
34 |
35 | private void initParticles()
36 | {
37 | particles = new Particle[capacity];
38 | for(int i = 0; i < particles.Length; i++)
39 | {
40 | particles[i] = new Particle();
41 | }
42 | }
43 |
44 | void swap(int indexA, int indexB)
45 | {
46 | Particle temp = particles[indexA];
47 | particles[indexA] = particles[indexB];
48 | particles[indexB] = temp;
49 | }
50 |
51 | void swapR(ref Particle A, ref Particle B)
52 | {
53 | Particle C = A;
54 | A = B;
55 | B = C;
56 | }
57 |
58 | ///
59 | /// Gets a new particle.
60 | ///
61 | /// A tuple: Item1 is the index of the particle, Item2 is the particle.
62 | public Particle getNew()
63 | {
64 | int current = countActive++;
65 |
66 | if (countActive > capacity)
67 | {
68 | countActive = capacity;
69 | return null;
70 | }
71 |
72 | return particles[current];
73 |
74 | }
75 |
76 | private bool checkIndex(int index)
77 | {
78 | return index >= 0 && index < particles.Length;
79 | }
80 |
81 |
82 | public Particle get(int index)
83 | {
84 | //return checkIndex(index) ? particles[index] : null;
85 | return particles[index];
86 | }
87 |
88 | public void activate(int index)
89 | {
90 | swap(index, countActive);
91 | countActive++;
92 | }
93 |
94 | public void deactivate(int index)
95 | {
96 | //if (checkIndex(index))
97 | {
98 | swap(index, countActive-1);
99 | countActive--;
100 | }
101 | }
102 |
103 | public int CountActive
104 | {
105 | get { return countActive; }
106 | }
107 |
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/platformerGame/Particles/cParticlePoolList.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Particles
8 | {
9 | class cParticlePoolList
10 | {
11 | List particles;
12 | int countActive;
13 |
14 | public cParticlePoolList(int max_particles)
15 | {
16 | particles = new List(max_particles);
17 | countActive = 0;
18 | }
19 |
20 | public Particle getNew()
21 | {
22 | Particle p = new Particle();
23 | particles.Add(p);
24 | countActive++;
25 | return p;
26 | }
27 |
28 | private bool checkIndex(int index)
29 | {
30 | return index >= 0 && index < particles.Count;
31 | }
32 |
33 | public Particle get(int index)
34 | {
35 | return particles[index];
36 | }
37 |
38 | public void deactivate(int index)
39 | {
40 | particles.RemoveAt(index);
41 | countActive--;
42 | }
43 |
44 | public int CountActive
45 | {
46 | get { return countActive; }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/platformerGame/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 |
8 | using platformerGame.App;
9 |
10 | namespace platformerGame
11 | {
12 | class Program
13 | {
14 | static void Main(string[] args)
15 | {
16 | SfmlApp gameApp = null;
17 |
18 | try
19 | {
20 | gameApp = new SfmlApp();
21 | gameApp.Run();
22 | }
23 | catch (Exception ex)
24 | {
25 | StreamWriter sw = new StreamWriter("ErrorLog_" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt");
26 | sw.WriteLine("Error created at " + DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss tt")); //yyyy/MM/dd HH:mm:ss:
27 | sw.WriteLine(ex.Message);
28 | sw.WriteLine(ex.Data.ToString());
29 |
30 | sw.WriteLine(ex.StackTrace);
31 | sw.Close();
32 |
33 | System.Diagnostics.Debug.WriteLine(ex.Message);
34 | System.Diagnostics.Debug.WriteLine(ex.Data.ToString());
35 | System.Diagnostics.Debug.WriteLine(ex.StackTrace);
36 | while (true) { }
37 |
38 | }
39 |
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/platformerGame/Regulator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame
8 | {
9 | class cRegulator
10 | {
11 | double freq;
12 | double periodTime; //in seconds
13 |
14 | //in milliseconds
15 | double currentTime = 0.0;
16 | double lastTime = 0.0;
17 |
18 | public cRegulator()
19 | {
20 | freq = 0.0;
21 | periodTime = 0.0;
22 | }
23 |
24 | public bool isReady()
25 | {
26 | currentTime = GlobalClock.GetTimeInMilliseconds();
27 |
28 | if ((currentTime - lastTime) >= periodTime * 1000.0)
29 | {
30 | lastTime = currentTime;
31 | return true;
32 | }
33 |
34 | return false;
35 | }
36 |
37 | public void resetByFrequency(double frequency)
38 | {
39 | this.freq = frequency;
40 | this.periodTime = (frequency > 0.0) ? (1.0 / frequency) : 0.0;
41 | lastTime = GlobalClock.GetTimeInMilliseconds();
42 | }
43 | public void resetByPeriodTime(float period_time_in_seconds)
44 | {
45 | this.periodTime = period_time_in_seconds;
46 | this.freq = (periodTime > 0.0) ? (1.0 / periodTime) : 0.0;
47 | lastTime = GlobalClock.GetTimeInMilliseconds();
48 | }
49 | public double getPeriodTime()
50 | {
51 | return periodTime;
52 | }
53 | public double getFrequency()
54 | {
55 | return freq;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/platformerGame/Rendering/RenderGroup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 |
9 | namespace platformerGame.Rendering
10 | {
11 | class RenderGroup : Drawable
12 | {
13 | List objects = new List();
14 | string id = "";
15 |
16 | public RenderGroup()
17 | {
18 |
19 | }
20 |
21 | // Ha valaki nem tudja hova kell hajózni, egyik szél se jó neki.
22 |
23 | public IEnumerable Objects
24 | {
25 | get { return this.objects;}
26 | }
27 |
28 | public void Add(IDrawable obj)
29 | {
30 |
31 | this.objects.Add(obj);
32 | }
33 |
34 | public virtual void PreRender(float alpha)
35 | {
36 |
37 | }
38 |
39 | public void Draw(RenderTarget target, RenderStates states)
40 | {
41 |
42 | }
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/platformerGame/Rendering/cAnimatedSpriteRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 |
11 | namespace platformerGame.Rendering
12 | {
13 | class cAnimatedSpriteRenderer : cBaseRenderer
14 | {
15 | public cAnimation AnimationSrc { get; set; }
16 |
17 | public cAnimatedSpriteRenderer(string sprite_id, MyIntRect view_offset_rect = null, bool repeat = false) : base()
18 | {
19 | AnimationInfo info = cAnimationAssets.Get(sprite_id);
20 |
21 | if(view_offset_rect != null)
22 | {
23 | info.ViewOffsetRect = view_offset_rect;
24 | }
25 |
26 | info.Repeat = repeat;
27 | AnimationSrc = new cAnimation(info);
28 | }
29 |
30 | protected cAnimatedSpriteRenderer(cAnimatedSpriteRenderer other) : base(other)
31 | {
32 | this.AnimationSrc = new cAnimation(other.AnimationSrc.AnimData);
33 | }
34 |
35 | // by: https://stackoverflow.com/questions/19119623/clone-derived-class-from-base-class-method
36 | public override cBaseRenderer DeepCopy()
37 | {
38 | return new cAnimatedSpriteRenderer(this);
39 | }
40 |
41 | public override void Update(float step_time)
42 | {
43 | AnimationSrc.Update();
44 | }
45 |
46 | public override void Draw(RenderTarget destination, Vector2f pos)
47 | {
48 | AnimationSrc.RenderCentered(destination, pos);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/platformerGame/Rendering/cAnimationAssets.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.Graphics;
7 | using platformerGame.Utilities;
8 |
9 | namespace platformerGame.Rendering
10 | {
11 | class AnimationInfo
12 | {
13 | public Texture refTexture { get; set; }
14 | public List Frames { get; set; }
15 | public MyIntRect ViewOffsetRect { get; set; }
16 | public bool Repeat { get; set; }
17 |
18 | public AnimationInfo(Texture texture, IEnumerable frames, MyIntRect view_offset, bool repeat = false)
19 | {
20 | this.refTexture = texture; // assets.GetTexture(texture_name);
21 | this.Frames = new List(frames);
22 | this.ViewOffsetRect = view_offset;
23 | this.Repeat = repeat;
24 | }
25 |
26 | /*
27 | public AnimationInfo(Texture texture, IEnumerable frames, MyIntRect view_offset, bool repeat = false)
28 | {
29 | this.refTexture = texture;
30 | this.Frames = new List(frames);
31 | this.ViewOffsetRect = view_offset;
32 | this.Repeat = repeat;
33 | }
34 | */
35 |
36 | public AnimationInfo(AnimationInfo other)
37 | {
38 | this.refTexture = other.refTexture;
39 | this.Frames = new List(other.Frames.ToArray());
40 | this.ViewOffsetRect = other.ViewOffsetRect;
41 | this.Repeat = other.Repeat;
42 | }
43 |
44 | public void setFramesByRef(List ref_frames)
45 | {
46 | this.Frames = ref_frames;
47 | }
48 |
49 | public AnimationInfo DeepCopy()
50 | {
51 | return new AnimationInfo(this);
52 | }
53 | }
54 |
55 | class cAnimationAssets
56 | {
57 | static Dictionary framesContainer = new Dictionary();
58 |
59 | static cAnimationAssets()
60 | {
61 | // framesContainer
62 | }
63 |
64 | public static IEnumerable getLoopedFull(int rows, int columns, int frame_width, int frame_height)
65 | {
66 | for (int i = 0; i < rows; i++)
67 | {
68 | for (int j = 0; j < columns; j++)
69 | {
70 | yield return new MyIntRect(j * frame_width, i * frame_height, frame_width, frame_height);
71 | }
72 | }
73 | }
74 |
75 | public static IEnumerable getLoopedRow(int start_row, int start_column, int num_frames, int frame_width, int frame_height)
76 | {
77 | for (int f = 0; f < num_frames; f++)
78 | {
79 | yield return new MyIntRect((start_column + f) * frame_width, start_row * frame_height, frame_width, frame_height);
80 | }
81 | }
82 |
83 | public static void LoadAnimations(AssetContext assets)
84 | {
85 | framesContainer.Add("coins-gold", new AnimationInfo(assets.GetTexture("coins"), getLoopedRow(0, 0, 8, 16, 16), new MyIntRect(0,0,16,16)));
86 | framesContainer.Add("coins-silver", new AnimationInfo(assets.GetTexture("coins"), getLoopedRow(1, 0, 8, 16, 16), new MyIntRect(0, 0, 16, 16)));
87 | framesContainer.Add("coins-copper", new AnimationInfo(assets.GetTexture("coins"), getLoopedRow(2, 0, 8, 16, 16), new MyIntRect(0, 0, 16, 16)));
88 | framesContainer.Add("side-explosion1", new AnimationInfo(assets.GetTexture("side_explosion1"), getLoopedFull(3, 5, 96, 96), new MyIntRect(0, 0, 96, 96)));
89 | framesContainer.Add("side-explosion2", new AnimationInfo(assets.GetTexture("explosion512"), getLoopedFull(3,5,104,100), new MyIntRect(0, 0, 104, 100)));
90 | framesContainer.Add("simple-explosion1", new AnimationInfo(assets.GetTexture("explosion32_B"), getLoopedFull(4, 4, 32, 32), new MyIntRect(0, 0, 32, 32)));
91 | framesContainer.Add("simple-explosion2", new AnimationInfo(assets.GetTexture("explosion32"), getLoopedFull(4, 4, 32, 32), new MyIntRect(0, 0, 32, 32)));
92 | framesContainer.Add("simple-explosion3", new AnimationInfo(assets.GetTexture("explosion196_C"), getLoopedFull(4, 4, 49, 49), new MyIntRect(0, 0, 49, 49)));
93 | framesContainer.Add("flash-black", new AnimationInfo(assets.GetTexture("flash_black_128"), getLoopedFull(4,4,128,128), new MyIntRect(0, 0, 128, 128)));
94 | }
95 |
96 | public static void ClearAll()
97 | {
98 | framesContainer.Clear();
99 | }
100 |
101 | public static AnimationInfo Get(string id)
102 | {
103 | AnimationInfo inf;
104 | if(framesContainer.TryGetValue(id, out inf))
105 | {
106 | return inf;
107 | }
108 |
109 | return null;
110 |
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/platformerGame/Rendering/cBaseRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 |
10 | namespace platformerGame.Rendering
11 | {
12 | abstract class cBaseRenderer
13 | {
14 | protected RenderStates renderStates;
15 |
16 | public cBaseRenderer()
17 | {
18 | this.renderStates = new RenderStates(BlendMode.Alpha);
19 | }
20 |
21 | protected cBaseRenderer(cBaseRenderer other)
22 | {
23 | this.renderStates = other.renderStates;
24 | }
25 |
26 | // by: https://stackoverflow.com/questions/19119623/clone-derived-class-from-base-class-method
27 | public abstract cBaseRenderer DeepCopy();
28 |
29 | public abstract void Update(float step_time);
30 | public abstract void Draw(RenderTarget destination, Vector2f pos);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/platformerGame/Rendering/cSpriteRenderer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Utilities;
10 |
11 | namespace platformerGame.Rendering
12 | {
13 | class cSpriteRenderer : cBaseRenderer
14 | {
15 | Sprite sprite;
16 |
17 | public cSpriteRenderer(string texture_name, MyIntRect texture_rect, AssetContext assets) : base()
18 | {
19 | this.sprite = new Sprite(assets.GetTexture(texture_name));
20 |
21 | this.sprite.TextureRect = texture_rect.AsSfmlIntRect();
22 | //this.sprite.Scale = new Vector2f(0.5f, 0.5f);
23 | //this.sprite.Rotation = (float)cAppMath.RadianToDegress(this.orientation);
24 |
25 | this.sprite.Origin = new Vector2f(texture_rect.Width / 2.0f, texture_rect.Height / 2.0f);
26 | }
27 |
28 | protected cSpriteRenderer(cSpriteRenderer other) : base(other)
29 | {
30 | this.sprite = new Sprite(other.sprite);
31 | //this.sprite.TextureRect = other.sprite.TextureRect;
32 | }
33 |
34 | public override cBaseRenderer DeepCopy()
35 | {
36 | return new cSpriteRenderer(this);
37 | }
38 |
39 | public override void Update(float step_time)
40 | {
41 | // empty function
42 | }
43 |
44 | public override void Draw(RenderTarget destination, Vector2f pos)
45 | {
46 | sprite.Position = pos;
47 | destination.Draw(sprite, renderStates);
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/platformerGame/SfmlApp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using SFML.Window;
4 | using SFML.Graphics;
5 | using SFML.System;
6 | using System.Threading;
7 |
8 | using OverlordEngine.Utilities;
9 |
10 | namespace OverlordEngine
11 | {
12 | class SfmlApp
13 | {
14 | RenderWindow mainWindow;
15 | Vector2u windowSize;
16 | Utilities.Timer appTimer;
17 | bool appRunning;
18 |
19 | IGame game = null;
20 |
21 | Color clearColor;
22 |
23 | Text timeText;
24 |
25 | View defaultView;
26 |
27 | bool vsync = false;
28 |
29 | public SfmlApp(IGame refGame)
30 | {
31 | this.game = refGame;
32 | }
33 |
34 | private void setupSFML()
35 | {
36 | windowSize = new Vector2u(1280, 720);
37 |
38 | //if WPF: m_MainWindow = new RenderWindow(formHandle);
39 | mainWindow = new RenderWindow(new VideoMode(windowSize.X, windowSize.Y, 32), "Platformer", Styles.Close);
40 | mainWindow.SetVisible(true);
41 | activateVSYNC();
42 | mainWindow.SetFramerateLimit(0);
43 | mainWindow.SetKeyRepeatEnabled(false);
44 |
45 | mainWindow.Closed += new EventHandler(OnClosed);
46 | mainWindow.KeyPressed += new EventHandler(OnKeyPressed);
47 | mainWindow.Resized += new EventHandler(OnResized);
48 | mainWindow.MouseButtonPressed += new EventHandler(OnMouseButtonPressed);
49 |
50 |
51 | clearColor = new Color(0, 0, 0, 255);
52 |
53 | this.defaultView = mainWindow.DefaultView;
54 | //resource-ok betöltése (font-ok és textúrák, képek a játékhoz)
55 | AssetManager.LoadResources();
56 | }
57 |
58 | private void init()
59 | {
60 | setupSFML();
61 |
62 | appTimer = new Utilities.Timer();
63 | //ChangeGameState( new cGameScene(this) );
64 |
65 |
66 | //Idő szöveg
67 | timeText = new Text("", AssetManager.GetFont("pf_tempesta_seven"));
68 | timeText.Position = new Vector2f(this.defaultView.Size.X-500, 30);
69 | timeText.CharacterSize = 28; // in pixels, not points!
70 | timeText.FillColor = Color.White;
71 | timeText.Style = Text.Styles.Bold;
72 |
73 | GlobalClock.Start();
74 |
75 | game.Init();
76 |
77 | appRunning = true;
78 |
79 | }
80 |
81 | private void toggleVSYNC()
82 | {
83 | vsync = !vsync;
84 | MainWindow.SetVerticalSyncEnabled(vsync);
85 | }
86 |
87 | private void activateVSYNC()
88 | {
89 | this.vsync = true;
90 | mainWindow.SetVerticalSyncEnabled(true);
91 | }
92 |
93 | private void deactivateVSYNC()
94 | {
95 | this.vsync = false;
96 | mainWindow.SetVerticalSyncEnabled(false);
97 | }
98 |
99 | private void beforeUpdate()
100 | {
101 | game.OnBeforeUpdate();
102 | }
103 |
104 | private void updateFixed(float step_time)
105 | {
106 | game.OnUpdateFixed(step_time);
107 | }
108 |
109 | private void updateVariable(float stepTime)
110 | {
111 | game.OnUpdateVariable(stepTime);
112 | }
113 |
114 | private void preRender(float alpha)
115 | {
116 | game.OnPreRender(alpha);
117 | }
118 |
119 | private void render(float alpha)
120 | {
121 | mainWindow.Clear(clearColor);
122 |
123 | game.OnRender(mainWindow);
124 |
125 | mainWindow.Display();
126 | }
127 |
128 | private void mainLoop()
129 | {
130 | // m_Timer.Start();
131 |
132 | Clock timer = new Clock();
133 | timer.Restart();
134 |
135 | const int MAX_FRAMESKIP = 5;
136 |
137 | float time, lastTime;
138 | time = timer.ElapsedTime.AsSeconds();
139 | lastTime = time;
140 |
141 | float delta = 1.0f;
142 | float maxDelta = 0.25f; //0.25f
143 | float acc = 0;
144 | float stepTime = Constants.STEP_TIME;
145 | int loops;
146 | float alpha = 0.0f;
147 |
148 | while (appRunning)
149 | {
150 |
151 | time = timer.ElapsedTime.AsSeconds();
152 | delta = time - lastTime;
153 | lastTime = time;
154 |
155 | //m_MainWindow.DispatchEvents();
156 |
157 | //m_DeltaTime = m_Timer.GetDeltaTime();
158 | //m_FPS = 1.0f / m_DeltaTime;
159 |
160 | if (delta > maxDelta)
161 | delta = maxDelta;
162 |
163 |
164 | acc += delta;
165 |
166 | /*
167 | float lagTreshold = MAX_FRAMESKIP * stepTime;
168 | if (acc > lagTreshold)
169 | {
170 | acc = lagTreshold;
171 | }
172 | */
173 |
174 | beforeUpdate();
175 |
176 | loops = 0;
177 | while (acc >= stepTime)
178 | {
179 | mainWindow.DispatchEvents();
180 | updateFixed(stepTime);
181 | acc -= stepTime;
182 |
183 | loops++;
184 |
185 | if(loops >= MAX_FRAMESKIP)
186 | {
187 | acc = 0.0f;
188 | break;
189 | }
190 |
191 | }
192 |
193 | updateVariable(1.0f);
194 |
195 | alpha = acc / stepTime;
196 | preRender(alpha);
197 | render(alpha);
198 | }
199 | }
200 |
201 |
202 | public void destroy()
203 | {
204 | game.Destroy();
205 | mainWindow.Close();
206 | }
207 |
208 | public void Run()
209 | {
210 | init();
211 | mainLoop();
212 | destroy();
213 | }
214 |
215 | ///
216 | /// Pl. kilépés menüre gombra kattintanak
217 | ///
218 | public void CloseApp()
219 | {
220 | appRunning = false;
221 | }
222 |
223 | /*
224 | public double FPS
225 | {
226 | get { return m_FPS; }
227 | }
228 | */
229 |
230 | /*
231 | public void ChangeGameState(cGameScene new_state)
232 | {
233 | if(game != null)
234 | game.Exit();
235 |
236 | //m_LastState = m_CurrentState;
237 | game = new_state;
238 | game.Enter();
239 | }
240 | */
241 |
242 | private void OnResized(object sender, SizeEventArgs e)
243 | {
244 | var view = mainWindow.GetView();
245 | view.Size = new Vector2f(windowSize.X, windowSize.Y); // (e.Width, e.Height);
246 | mainWindow.SetView(view);
247 | }
248 |
249 | private void OnClosed(object sender, EventArgs e)
250 | {
251 | appRunning = false;
252 | }
253 |
254 | private void OnKeyPressed(object sender, KeyEventArgs e)
255 | {
256 |
257 | if (e.Code == Keyboard.Key.Escape)
258 | appRunning = false;
259 |
260 | if (e.Code == Keyboard.Key.V)
261 | toggleVSYNC();
262 |
263 | game.OnKeyPressed(e);
264 | }
265 |
266 | private void OnMouseButtonPressed(object sender, MouseButtonEventArgs e)
267 | {
268 | game.OnSingleMouseClick(e);
269 | }
270 |
271 |
272 | public RenderWindow MainWindow
273 | {
274 | get { return mainWindow; }
275 | }
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/platformerGame/ShakeScreen.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.System;
8 | using platformerGame.Utilities;
9 |
10 | namespace platformerGame
11 | {
12 | static class ShakeScreen
13 | {
14 | static Vector2f m_DefaultCenter;
15 | static Vector2f m_Offset;
16 |
17 | static Vector2f m_CurrentCenterPos;
18 | static float m_CurrentRadius;
19 | static float m_CurrentAngle;
20 |
21 | static float m_StartRadius;
22 | static float m_MinShakeRadius;
23 | static float m_DiminishFactor;
24 |
25 | static bool shaking;
26 |
27 | static ShakeScreen()
28 | {
29 | shaking = false;
30 | }
31 |
32 | public static void Init(Vector2f default_center)
33 | {
34 | m_DefaultCenter = default_center;
35 | }
36 |
37 | public static void StopShake()
38 | {
39 | shaking = false;
40 | m_Offset = new Vector2f(0.0f, 0.0f);
41 | m_CurrentCenterPos = new Vector2f(0.0f, 0.0f); //m_DefaultCenter;
42 | }
43 | //=====================================================================================================
44 | public static void StartShake(float start_radius = 5.0f, float min_shake_radius = 1.0f, float dimin_factor = 0.925f)
45 | {
46 | shaking = true;
47 | m_CurrentCenterPos = m_DefaultCenter;
48 | //m_Offset = new Vector2f(0.0f, 0.0f);
49 | m_CurrentAngle = (float)AppRandom.GetRandomNumber(0, 360);
50 | m_CurrentRadius = start_radius;
51 | m_MinShakeRadius = min_shake_radius;
52 | m_DiminishFactor = dimin_factor;
53 | }
54 |
55 |
56 | public static void Update()
57 | {
58 | if(shaking)
59 | {
60 | m_CurrentRadius *= m_DiminishFactor; //diminish radius each frame
61 | m_CurrentAngle += (150.0f + AppRandom.GetRandomNumber(0, 60)); //pick new angle
62 | float rad = (float)AppMath.DegressToRadian(m_CurrentAngle);
63 | m_Offset = new Vector2f((float)Math.Sin(rad) * m_CurrentRadius, (float)Math.Cos(rad) * m_CurrentRadius); //create offset 2d vector
64 |
65 | m_CurrentCenterPos = m_DefaultCenter + m_Offset;
66 | //set centre of viewport
67 |
68 | if (m_CurrentRadius < m_MinShakeRadius) //2.0f
69 | StopShake();
70 |
71 | }
72 |
73 |
74 | }
75 |
76 | public static Vector2f Offset
77 | {
78 | get { return m_Offset; }
79 | }
80 |
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/platformerGame/StateBase/IState.cs:
--------------------------------------------------------------------------------
1 | using SFML.Graphics;
2 |
3 | namespace platformerGame.StateBase
4 | {
5 | interface IState
6 | {
7 | void Create();
8 | void Enter(IState prev_state = null);
9 | void UpdateFixed(float step_time);
10 | void UpdateVariable();
11 | void Exit();
12 | }
13 |
14 | interface IVisualStateComponent
15 | {
16 | // rendering calculations, ordering (eg. view position calculation...etc)
17 | void PreRender(float alpha);
18 | void Render(RenderTarget destination);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/AppRandom.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.System;
7 |
8 | namespace platformerGame.Utilities
9 | {
10 | class AppRandom
11 | {
12 | private static Random random;
13 |
14 | static AppRandom()
15 | {
16 | random = new Random();
17 | }
18 | ///
19 | /// Chooses a random item from the given array
20 | ///
21 | /// type of the array
22 | ///
23 | /// 0 to len to choose, if -1, the length of the array used
24 | ///
25 | public static T Choose(T[] array, int len = -1)
26 | {
27 | return array[ random.Next(0, (len < 0) ? array.Length : len) ];
28 | }
29 |
30 | ///
31 | /// Chooses a random item from the given list
32 | ///
33 | ///
34 | ///
35 | ///
36 | public static T Chooose(List list)
37 | {
38 | return list[random.Next(0, list.Count)];
39 | }
40 |
41 | ///
42 | /// Gets a random number in the specified range (max param excluded).
43 | ///
44 | ///
45 | ///
46 | ///
47 | public static int GetRandomNumber(int min, int max)
48 | {
49 | return random.Next(min, max);
50 | }
51 |
52 | ///
53 | /// Gets a random float between 0 and 1.
54 | ///
55 | ///
56 | public static float GetRandomFloat()
57 | {
58 | return (float)random.NextDouble();
59 | }
60 |
61 | public static double GetRandomDouble()
62 | {
63 | return random.NextDouble();
64 | }
65 |
66 | public static double GetRandomClamped()
67 | {
68 | return GetRandomDouble() - GetRandomDouble();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/AppTimer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using System.Diagnostics;
8 |
9 | using SFML.System;
10 |
11 | namespace platformerGame.Utilities
12 | {
13 | class AppTimer
14 | {
15 | private Stopwatch m_Timer; //SFML beépített clock-ja
16 |
17 | private double m_CurrentTime;
18 | private double m_LastTime;
19 |
20 | public AppTimer()
21 | {
22 | m_Timer = new Stopwatch();
23 | }
24 |
25 | public void Start()
26 | {
27 | m_Timer.Start();
28 | m_CurrentTime = m_Timer.Elapsed.TotalSeconds;
29 |
30 | m_LastTime = m_CurrentTime;
31 | }
32 | public double GetCurrentTime()
33 | {
34 | return m_Timer.Elapsed.TotalSeconds;
35 | }
36 |
37 | public double GetCurrentTimeAsMilliseconds()
38 | {
39 | return m_Timer.Elapsed.TotalMilliseconds;
40 | }
41 | ///
42 | /// Megmondja az eltelt időt az előző hívás óta (másodpercben). Frame-nként hívva megmondja a framek között eltelt (delta) időt, amire szükségünk van.
43 | ///
44 | ///
45 | public double GetDeltaTime()
46 | {
47 | m_CurrentTime = GetCurrentTime();
48 | double dt = m_CurrentTime - m_LastTime;
49 | m_LastTime = m_CurrentTime;
50 | return dt;
51 | }
52 |
53 | public override string ToString()
54 | {
55 | cTimeInfo tinfo = new cTimeInfo(this.GetCurrentTime());
56 | return tinfo.ToString();
57 | }
58 |
59 | /*
60 | private Clock m_Timer; //SFML beépített clock-ja
61 |
62 | private float m_CurrentTime;
63 | private float m_LastTime;
64 | public cTimer()
65 | {
66 | m_Timer = new Clock();
67 | }
68 |
69 | public void Start()
70 | {
71 | m_CurrentTime = m_Timer.Restart().AsSeconds();
72 | m_LastTime = m_CurrentTime;
73 | }
74 | public float GetCurrentTime()
75 | {
76 | return m_Timer.ElapsedTime.AsSeconds();
77 | }
78 |
79 | public float GetCurrentTimeAsMilliseconds()
80 | {
81 | return m_Timer.ElapsedTime.AsMilliseconds();
82 | }
83 | ///
84 | /// Megmondja az eltelt időt az előző hívás óta (másodpercben). Frame-nként hívva megmondja a framek között eltelt (delta) időt, amire szükségünk van.
85 | ///
86 | ///
87 | public float GetDeltaTime()
88 | {
89 | m_CurrentTime = GetCurrentTime();
90 | float dt = m_CurrentTime - m_LastTime;
91 | m_LastTime = m_CurrentTime;
92 | return dt;
93 | }
94 |
95 | public override string ToString()
96 | {
97 | cTimeInfo tinfo = new cTimeInfo(this.GetCurrentTime());
98 | return tinfo.ToString();
99 | }
100 | */
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/Constants.cs:
--------------------------------------------------------------------------------
1 | using SFML.System;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | using SFML.Graphics;
9 | using Newtonsoft.Json;
10 | using Newtonsoft.Json.Linq;
11 |
12 | using System.IO;
13 |
14 | namespace platformerGame.Utilities
15 | {
16 | class Constants
17 | {
18 | public const float STEP_TIME = 1.0f / 60.0f;
19 | public const uint ANIM_FRAME_TIME = 30; //in ms
20 |
21 | public static int TILE_SIZE = 16;
22 | public static int TILE_SIZE_HALF = TILE_SIZE / 2;
23 |
24 | [JsonProperty("monster-walk-speed")]
25 | public static float MONSTER_WALK_SPEED { get; private set; } //300.0f;
26 |
27 | [JsonProperty("player-walk-speed")]
28 | public static float PLAYER_WALK_SPEED { get; private set; } //300.0f;
29 |
30 | [JsonProperty("monster-max-walk-speed")]
31 | public static float MONSTER_MAX_WALK_SPEED { get; private set; } //200.0f;
32 |
33 | [JsonProperty("player-max-walk-speed")]
34 | public static float PLAYER_MAX_WALK_SPEED { get; private set; } //200.0f;
35 |
36 | [JsonProperty("ground-slowdown-factor")]
37 | public static float GROUND_SLOW_DOWN_FACTOR { get; private set; } //0.745f;
38 |
39 | [JsonProperty("air-slowdown-factor")]
40 | public static float AIR_SLOW_DOWN_FACTOR { get; private set; }
41 |
42 | [JsonProperty("jump-speed")]
43 | public static float JUMP_SPEED { get; private set; } //210 250
44 |
45 | [JsonProperty("max-Y-speed")]
46 | public static float MAX_Y_SPEED { get; private set; } //290.0f; //400
47 |
48 | [JsonProperty("gravity")]
49 | public static float GRAVITY { get; private set; } //680 781.25f
50 |
51 | [JsonProperty("jump-gravity")]
52 | public static float JUMP_GRAVITY { get; private set; } //212.5f; 260
53 |
54 | [JsonProperty("bullet-hit-force")]
55 | public static float BULLET_HIT_FORCE { get; private set; }
56 |
57 | [JsonProperty("bullet-start-speed")]
58 | public static float BULLET_START_SPEED { get; private set; }
59 |
60 | [JsonProperty("bullet-texture-name")]
61 | public static string BULLET_TEXTURE_NAME { get; private set; }
62 |
63 | [JsonProperty("default-weapon-firing-frequency")]
64 | public static int DEFAULT_WEAPON_FIRING_FREQUENCY { get; private set; }
65 |
66 | [JsonProperty("friction")]
67 | public static float FRICTION { get; private set; } //0.02f;
68 |
69 | [JsonProperty("restitution")]
70 | public static float RESTITUTION { get; private set; } //0.1f;
71 |
72 | [JsonProperty("glue")]
73 | public static float GLUE { get; private set; } //0.01f;
74 |
75 | [JsonProperty("character-frame-width")]
76 | public static int CHAR_FRAME_WIDTH { get; private set; }
77 |
78 | [JsonProperty("character-frame-height")]
79 | public static int CHAR_FRAME_HEIGHT { get; private set; } //48
80 |
81 | [JsonProperty("player-texture-name")]
82 | public static string PLAYER_TEXTURE_NAME { get; private set; }
83 |
84 | [JsonProperty("monster-texture-name")]
85 | public static string MONSTER_TEXTURE_NAME { get; private set; }
86 |
87 | [JsonProperty("monster-max-health")]
88 | public static int MONSTER_MAX_HEALTH { get; private set; }
89 |
90 | [JsonProperty("character-collision-rect")]
91 | public static MyIntRect CHAR_COLLISON_RECT { get; private set; } // = new IntRect(10, 0, 22, 32); //32-10 = 22 | 10:left, 32:width
92 |
93 | [JsonProperty("character-view-rect")]
94 | public static MyIntRect CHAR_VIEW_RECT { get; private set; } // = new IntRect(5, 0, 27, 32);
95 |
96 | [JsonProperty("lightmap-color")]
97 | public static Color LIGHTMAP_COLOR { get; private set; }
98 |
99 | [JsonProperty("background-color")]
100 | public static Color BACKGROUND_COLOR { get; private set; }
101 |
102 | [JsonProperty("font-names")]
103 | public static string[] FONT_NAMES { get; private set; }
104 |
105 | [JsonProperty("texture-names")]
106 | public static string[] TEXTURES_NAMES { get; private set; }
107 |
108 | [JsonProperty("sound-names")]
109 | public static string[] SOUND_NAMES { get; private set; }
110 |
111 | [JsonProperty("bg-texture")]
112 | public static string BG_TEXTURE { get; private set; }
113 |
114 | static Constants()
115 | {
116 | }
117 |
118 | public static void Load()
119 | {
120 | if (File.Exists("constants.json"))
121 | {
122 | string json = File.ReadAllText(@"constants.json");
123 | FromJson(json);
124 | }
125 | else
126 | throw new FileNotFoundException("The constants.json file is missing.");
127 | }
128 |
129 | private static Constants FromJson(string json) => JsonConvert.DeserializeObject(json, new JsonSerializerSettings
130 | {
131 | MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
132 | DateParseHandling = DateParseHandling.None,
133 | }
134 | );
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/MyRect.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.Graphics;
7 |
8 | namespace platformerGame.Utilities
9 | {
10 | class MyRect where T : struct
11 | {
12 | public T Left { get; set; }
13 | public T Top { get; set; }
14 | public T Width { get; set; }
15 | public T Height { get; set; }
16 |
17 | public MyRect()
18 | {
19 | Left = Top = Width = Height = default(T);
20 | }
21 |
22 | public MyRect(T left, T top, T w, T h)
23 | {
24 | this.Left = left;
25 | this.Top = top;
26 | this.Width = w;
27 | this.Height = h;
28 | }
29 |
30 | public MyRect(MyRect other) : this(other.Left,other.Top,other.Width,other.Height)
31 | {
32 | }
33 |
34 | public MyRect DeepCopy()
35 | {
36 | return new MyRect(this);
37 | }
38 |
39 | public MyRect ShallowCopy()
40 | {
41 | return (MyRect)this.MemberwiseClone();
42 | }
43 | }
44 |
45 | class MyIntRect : MyRect
46 | {
47 |
48 | public MyIntRect() : base()
49 | {
50 | }
51 |
52 | public MyIntRect(int left, int top, int w, int h) : base(left,top,w,h)
53 | {
54 | }
55 |
56 | public MyIntRect(MyIntRect other) : base(other.Left, other.Top, other.Width, other.Height)
57 | {
58 | }
59 |
60 | public new MyIntRect DeepCopy()
61 | {
62 | return new MyIntRect(this);
63 | }
64 |
65 | public IntRect AsSfmlIntRect()
66 | {
67 | return new IntRect(Left, Top, Width, Height);
68 | }
69 |
70 | }
71 |
72 |
73 | class MyFloatRect : MyRect
74 | {
75 | public MyFloatRect() : base()
76 | {
77 | }
78 |
79 | public MyFloatRect(float left, float top, float w, float h) : base(left, top, w, h)
80 | {
81 | }
82 |
83 | public MyFloatRect(MyFloatRect other) : base(other.Left, other.Top, other.Width, other.Height)
84 | {
85 | }
86 |
87 | public new MyFloatRect DeepCopy()
88 | {
89 | return new MyFloatRect(this);
90 | }
91 |
92 | public FloatRect AsSfmlFloatRect()
93 | {
94 | return new FloatRect(Left, Top, Width, Height);
95 | }
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/ProbabilityRoll.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Utilities
8 | {
9 | ///
10 | /// Weight - value table. Seed the table with weight - value pairs,
11 | /// then by using roll() function, itt will pick randomly a weight(proportion),
12 | /// and then returns the specified type of value.
13 | /// Bigger weight, bigger chance...
14 | /// NOTE: strinsg has no default constructor, so cant be used
15 | ///
16 | /// T is the type of the value
17 | class ProbabilityRoll where T : new()
18 | {
19 | ///
20 | /// the first type of the tuple is weight, second is value
21 | ///
22 | List< Tuple > probabilityTable;
23 |
24 | public ProbabilityRoll()
25 | {
26 | probabilityTable = new List>();
27 | }
28 |
29 | ///
30 | /// Uploads the probability table by adding weights - values pairs.
31 | ///
32 | /// array of the weight - value pairs
33 | ///
34 | public void seed(Tuple[] wv_pairs)
35 | {
36 | probabilityTable.Clear();
37 |
38 | foreach (var p in wv_pairs)
39 | {
40 | probabilityTable.Add(p);
41 | }
42 | }
43 |
44 | ///
45 | /// Uploads the probability table with weights and values.
46 | /// Arrays must have same sizes.
47 | ///
48 | /// array of weights
49 | /// array of values
50 | /// false, if the length of weights and values not equals, else true.
51 | public bool seed(int[] weights, T[] values)
52 | {
53 | if(weights.Length != values.Length)
54 | {
55 | return false;
56 | }
57 |
58 | int len = weights.Length;
59 | probabilityTable.Clear();
60 |
61 | for(int i = 0; i < len; i++)
62 | {
63 | probabilityTable.Add(new Tuple(weights[i], values[i]));
64 | }
65 |
66 | return true;
67 | }
68 |
69 | public void add(int weight, T value)
70 | {
71 | probabilityTable.Add(new Tuple(weight, value));
72 | }
73 |
74 | public void clear()
75 | {
76 | probabilityTable.Clear();
77 | }
78 |
79 | private T lookupValue(int x)
80 | {
81 | // assume 0 ≤ x < sum_of_weights
82 | int cumulative_weight = 0;
83 |
84 | for (var row = 0; row < probabilityTable.Count; row++)
85 | {
86 | cumulative_weight += probabilityTable[row].Item1;
87 | if (x < cumulative_weight)
88 | {
89 | return probabilityTable[row].Item2;
90 | }
91 | }
92 |
93 | // should never run, because the condition inside for loop should evaulate true sometime,
94 | // so we always return from there.
95 | return default(T); //Activator.CreateInstance();
96 | }
97 |
98 | public T roll(bool use_empty = false)
99 | {
100 | int sum_of_weights = 0;
101 | for (var row = 0; row < probabilityTable.Count; row++)
102 | {
103 |
104 | sum_of_weights += probabilityTable[row].Item1;
105 | }
106 |
107 | int x = AppRandom.GetRandomNumber(0, use_empty ? 100 : sum_of_weights);
108 | return lookupValue(x);
109 | }
110 |
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 |
9 | namespace platformerGame.Utilities
10 | {
11 | public static class Utils
12 | {
13 | public static readonly Color RED = new Color(255, 82, 82);
14 | public static readonly Color BLUE = new Color(99, 196, 236);
15 |
16 | //==========================================================================================================
17 | public static Color GetRandomRedColor()
18 | {
19 | Color c = GetRandomColor(200, 255, 5, 90, 5, 90); // (160, 255, 20, 80, 20, 80);
20 | return c;
21 | }
22 | //==========================================================================================================
23 | public static Color GetRandomOrangeColor()
24 | {
25 | Color c = GetRandomColor(220, 255, 130, 160, 50, 70); // (160, 255, 20, 80, 20, 80);
26 | return c;
27 | }
28 | //==========================================================================================================
29 | public static Color GetRandomGreenColor()
30 | {
31 | Color c = GetRandomColor(20, 100, 160, 255, 20, 100);
32 | return c;
33 | }
34 | //==========================================================================================================
35 | public static Color GetRandomBlueColor()
36 | {
37 | Color c = GetRandomColor(37, 99, 150, 196, 220, 236);
38 | return c;
39 | }
40 | //==========================================================================================================
41 | public static Color GetRandomColor(byte minR, byte maxR, byte minG, byte maxG, byte minB, byte maxB)
42 | {
43 | Color c = new Color();
44 |
45 | c.R = AppMath.GetRandomByte(minR, maxR);
46 | c.G = AppMath.GetRandomByte(minG, maxG);
47 | c.B = AppMath.GetRandomByte(minB, maxB);
48 | c.A = 255;
49 | return c;
50 | }
51 |
52 | //==========================================================================================================
53 | public static void Swap(ref T a, ref T b)
54 | {
55 | T c = a;
56 | a = b;
57 | b = c;
58 | }
59 | //==========================================================================================================
60 | public static Color GetSfmlColorFromHex(string hex_color)
61 | {
62 | System.Drawing.Color c = System.Drawing.ColorTranslator.FromHtml(hex_color);
63 | return new Color(c.R, c.G, c.B, c.A);
64 | }
65 | //==========================================================================================================
66 | public static void RemoveAll(this Dictionary dict, Func, bool> match)
67 | {
68 | foreach (var cur in dict.Where(match).ToList())
69 | {
70 | dict.Remove(cur.Key);
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/platformerGame/Utilities/cTimeInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame.Utilities
8 | {
9 | class cTimeInfo
10 | {
11 | double seconds;
12 |
13 | public cTimeInfo()
14 | {
15 | seconds = 0.0f;
16 | }
17 |
18 | public cTimeInfo(double sec)
19 | {
20 | seconds = sec;
21 | }
22 | public double Seconds
23 | {
24 | get { return seconds; }
25 | set { seconds = value; }
26 | }
27 |
28 | public override string ToString()
29 | {
30 | int min = (int)(seconds / 60);
31 | int sec = ((int)seconds % 60);
32 | int sec2 = sec / 10;
33 | int sec3 = sec % 10;
34 |
35 | return String.Format("{0}:{1}{2}", min, sec2, sec3);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/platformerGame/cAnimation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 | using platformerGame.Rendering;
10 | using platformerGame.Utilities;
11 |
12 | namespace platformerGame
13 | {
14 | class cAnimation
15 | {
16 | AnimationInfo animData;
17 |
18 | bool m_FlipHorizontally;
19 | bool m_FlipVertically;
20 |
21 | uint m_FrameTime; //in milliseconds
22 | uint m_StartFrame;
23 |
24 | int m_CurrentFrame;
25 | double m_CurrentAnimTime;
26 | double m_LastAnimTime;
27 |
28 | // MyIntRect viewOffsetRect; //view rect offsets inside animation rect
29 |
30 | public bool Active { get; set; }
31 |
32 | public cAnimation(Texture sprite_sheet, MyIntRect view_offset_rect)
33 | {
34 | animData = new AnimationInfo(sprite_sheet, new List(), view_offset_rect);
35 | init();
36 | }
37 |
38 | public cAnimation(AnimationInfo ref_anim)
39 | {
40 | this.animData = ref_anim;
41 | this.SetFrames(ref_anim.Frames);
42 | init();
43 | }
44 |
45 | public void init()
46 | {
47 | m_FlipHorizontally = false;
48 | m_FlipVertically = false;
49 | m_CurrentFrame = 0;
50 | Active = true;
51 | m_CurrentAnimTime = GlobalClock.GetTimeInMilliseconds();
52 | m_FrameTime = Constants.ANIM_FRAME_TIME;
53 | m_LastAnimTime = m_CurrentAnimTime;
54 | }
55 |
56 | private bool _isReadyForNextFrame()
57 | {
58 | m_CurrentAnimTime = GlobalClock.GetTimeInMilliseconds();
59 | return (m_CurrentAnimTime - m_LastAnimTime >= m_FrameTime);
60 | }
61 |
62 | public void Update()
63 | {
64 | if (this.GetSize() > 1)
65 | {
66 | if (_isReadyForNextFrame())
67 | {
68 | m_LastAnimTime = GlobalClock.GetTimeInMilliseconds();
69 |
70 | m_CurrentFrame += 1;
71 |
72 | if (m_CurrentFrame >= this.GetSize()) //myCurrentFrame < 0
73 | {
74 | if(this.animData.Repeat)
75 | {
76 | m_CurrentFrame = 0;
77 | return;
78 | }
79 | m_CurrentFrame = this.GetSize() - 1;
80 | Active = false;
81 | }
82 | }
83 | }
84 | else
85 | m_CurrentFrame = 0;
86 |
87 | }
88 |
89 | public void RenderCentered(RenderTarget destination, Vector2f pos)
90 | {
91 | MyIntRect frame = this.GetCurrentFrame().DeepCopy();
92 |
93 | frame.Left += this.animData.ViewOffsetRect.Left;
94 | frame.Top += this.animData.ViewOffsetRect.Top;
95 |
96 | frame.Width = this.animData.ViewOffsetRect.Width;
97 | frame.Height = this.animData.ViewOffsetRect.Height;
98 |
99 | DrawingBase.DrawTextureUseCenter(destination,
100 | pos,
101 | this.GetTexture(),
102 | frame,
103 | Color.White,
104 | 0.0f,
105 | 1.0f, //SCALE_FACTOR,
106 | false, //p_myCurrentAnim->IsFlippedHorizontally(),
107 | false,
108 | BlendMode.Add,
109 | null);
110 | }
111 |
112 | public void Render(RenderTarget destination, Vector2f pos) //MyIntRect view_rect = new MyIntRect()
113 | {
114 | MyIntRect frame = this.GetCurrentFrame().DeepCopy(); //.DeepCopy is very important for drawing!!
115 |
116 | frame.Left += this.animData.ViewOffsetRect.Left;
117 | frame.Top += this.animData.ViewOffsetRect.Top;
118 |
119 | frame.Width = this.animData.ViewOffsetRect.Width;
120 | frame.Height = this.animData.ViewOffsetRect.Height;
121 |
122 | /*
123 | cRenderFunctions.DrawTextureSimple( destination,
124 | pos,
125 | this.GetSpriteSheet(),
126 | frame,
127 | Color.White,
128 | BlendMode.Alpha
129 | );
130 | */
131 |
132 |
133 | DrawingBase.DrawTexture(destination,
134 | pos,
135 | this.GetTexture(),
136 | frame,
137 | Color.White,
138 | 0.0f,
139 | 1.0f, //SCALE_FACTOR,
140 | false, //p_myCurrentAnim->IsFlippedHorizontally(),
141 | false,
142 | BlendMode.Alpha,
143 | null);
144 |
145 | }
146 |
147 | public void Clear()
148 | {
149 | this.animData.Frames.Clear();
150 | }
151 | public bool FlipHorizontally
152 | {
153 | get { return m_FlipHorizontally; }
154 | set { m_FlipHorizontally = value; }
155 | }
156 | public bool FlipVertically
157 | {
158 | get { return m_FlipVertically; }
159 | set { m_FlipVertically = value; }
160 | }
161 |
162 | public void AddFrame(MyIntRect rect)
163 | {
164 | this.animData.Frames.Add(rect);
165 | }
166 |
167 | public void SetFrames(List frames)
168 | {
169 | this.animData.Frames = new List(frames);
170 | }
171 |
172 | /*
173 | public void SetSpriteSheet(Texture texture)
174 | {
175 | m_pTexture = texture;
176 | }
177 | */
178 | public Texture GetTexture()
179 | {
180 | return animData.refTexture;
181 | }
182 |
183 | public AnimationInfo AnimData
184 | {
185 | get { return this.animData; }
186 | }
187 |
188 | public int GetSize()
189 | {
190 | return this.animData.Frames.Count;
191 | }
192 |
193 | public MyIntRect GetCurrentFrame()
194 | {
195 | return GetFrame(m_CurrentFrame);
196 | }
197 |
198 | public MyIntRect GetFrame(int n)
199 | {
200 | //n = cAppMath.Clamp(n, 0, GetSize());
201 | //n = n < 0 ? 0 : n >= GetSize() ? GetSize() : n;
202 | /* if (m_Frames.Count > 0)
203 | return m_Frames[n];
204 | else
205 | return new MyIntRect(0, 0, 32, 32);*/
206 |
207 | return animData.Frames.Count > 0 ? animData.Frames[n] : new MyIntRect(0,0,1,1);
208 | }
209 |
210 | public void SetStartFrame(uint start_frame) { m_StartFrame = start_frame; }
211 | public uint GetStartFrame() {return m_StartFrame;}
212 |
213 | public void SetFrameTime(uint frame_time) { m_FrameTime = frame_time; }
214 | public uint GetFrameTime() {return m_FrameTime;}
215 |
216 | ~cAnimation()
217 | {
218 |
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/platformerGame/cEnvironment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 |
10 | using platformerGame.Utilities;
11 |
12 | namespace platformerGame
13 | {
14 | class cEnvironmentItem
15 | {
16 | protected Sprite sprite;
17 | protected AABB bounds; //may differ from drawing bounds
18 |
19 | public cEnvironmentItem(Texture texture)
20 | {
21 | sprite = new Sprite(texture);
22 | bounds = new AABB();
23 | }
24 |
25 | public cEnvironmentItem(Vector2f pos, Texture texture, AABB _bounds = null)
26 | {
27 | sprite = new Sprite(texture);
28 | sprite.Position = pos;
29 | bounds = _bounds ?? new AABB(pos, new Vector2f(texture.Size.X, texture.Size.Y));
30 | }
31 |
32 | public Sprite Sprite
33 | {
34 | get { return sprite; }
35 | //set { sprite = value; }
36 | }
37 |
38 | public AABB Bounds
39 | {
40 | get { return bounds; }
41 | set { bounds = value; }
42 | }
43 | }
44 | class cEnvironment
45 | {
46 | List envItems;
47 |
48 | List waterBlocks;
49 |
50 | public cEnvironment()
51 | {
52 | envItems = new List();
53 |
54 | }
55 |
56 | public void SetWaterBlocks(List wb_from_map)
57 | {
58 | waterBlocks = wb_from_map;
59 | }
60 | public void PlaceItem(Vector2f centre_pos, Texture texture)
61 | {
62 | //TODO: set pos by centre
63 | /*
64 | cEnvironmentItem item = new cEnvironmentItem();
65 | envItems.Add(item);
66 | */
67 | }
68 |
69 | public void PlaceOnGround(Vector2f on_ground_pos, Texture texture)
70 | {
71 | float x = on_ground_pos.X - texture.Size.X / 2.0f;
72 | float y = on_ground_pos.Y + Constants.TILE_SIZE - texture.Size.Y;
73 |
74 | cEnvironmentItem item = new cEnvironmentItem(new Vector2f(x,y), texture);
75 | envItems.Add(item);
76 | }
77 |
78 | ///
79 | /// Calculates bounding box for an item on the ground by giving its texture size.
80 | ///
81 | ///
82 | ///
83 | ///
84 | public AABB CalcBBOnGroundByTexture(Vector2f on_ground_pos, Vector2f texture_size)
85 | {
86 | float x = on_ground_pos.X - texture_size.X / 2.0f;
87 | float y = on_ground_pos.Y + Constants.TILE_SIZE - texture_size.Y;
88 |
89 | return new AABB(x, y, texture_size.X, texture_size.Y);
90 | }
91 | public void PlaceOnGround(Vector2f texture_pos, Texture texture, AABB bounding_rect)
92 | {
93 |
94 | cEnvironmentItem item = new cEnvironmentItem(texture_pos, texture, bounding_rect);
95 | envItems.Add(item);
96 | }
97 |
98 |
99 | public void ClearAll()
100 | {
101 | envItems.Clear();
102 | waterBlocks.Clear();
103 | }
104 | public void Update(float step_time)
105 | {
106 | foreach (cWaterBlock wb in waterBlocks)
107 | {
108 | wb.Update(step_time);
109 | }
110 | }
111 |
112 | public void RenderWaterBlocks(RenderTarget destination)
113 | {
114 |
115 | foreach (cWaterBlock wb in waterBlocks)
116 | {
117 | wb.Render(destination);
118 | }
119 | }
120 | public void RenderEnvironment(RenderTarget destination)
121 | {
122 |
123 | RenderStates rs = new RenderStates(BlendMode.Alpha);
124 |
125 | foreach (cEnvironmentItem item in envItems)
126 | {
127 |
128 | //destination.Draw(item.Sprite, rs);
129 | #if DEBUG
130 | RectangleShape rect = new RectangleShape();
131 | rect.Position = item.Bounds.topLeft;
132 | rect.Size = item.Bounds.dims;
133 | rect.OutlineColor = Color.Green;
134 | rect.OutlineThickness = 2.0f;
135 | rect.FillColor = Color.Transparent;
136 |
137 | destination.Draw(rect, rs);
138 |
139 | #else
140 | destination.Draw(item.Sprite, rs);
141 | #endif
142 | }
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/platformerGame/cLight.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.Graphics;
7 | using SFML.System;
8 |
9 | using platformerGame.Utilities;
10 |
11 | namespace platformerGame
12 | {
13 | class cLight
14 | {
15 | public Vector2f Pos { get; set; } //Center
16 | public Vector2f Dir { get; set; } //Direction of the Light
17 |
18 | private Color color;
19 | private Vector3f glColor;
20 | public Color OriginalColor { get; set; }
21 |
22 | public float Opacity { get; set; }
23 |
24 | public float Radius { get; set; }
25 | public float SpreadAngle { get; set; }
26 |
27 | //for light autenuation shader
28 | public float Bleed { get; set; }
29 | public float LinearizeFactor { get; set; }
30 |
31 | public bool Active { get; set; }
32 |
33 | public cLight()
34 | {
35 | Pos = new Vector2f(0, 0);
36 | Dir = new Vector2f(0, 0);
37 | Color = new Color(255, 255, 255, 255);
38 | OriginalColor = color;
39 | Opacity = 255.0f;
40 | Radius = 20.0f;
41 | SpreadAngle = (float)AppMath.TWO_PI;
42 | Bleed = 1.0f;
43 | LinearizeFactor = 0.6f;
44 | Active = true;
45 | }
46 |
47 | public cLight(Vector2f pos) : this()
48 | {
49 | Pos = pos;
50 | }
51 |
52 | public void TurnOn()
53 | {
54 | Color = new Color(OriginalColor);
55 | }
56 |
57 | public void TurnOff()
58 | {
59 | Color = new Color(0, 0, 0, 0);
60 | }
61 |
62 | public Color Color
63 | {
64 | get { return color; }
65 | set
66 | {
67 | color = value;
68 | glColor.X = ((float)color.R / 255.0f);
69 | glColor.Y = ((float)color.G / 255.0f);
70 | glColor.Z = ((float)color.B / 255.0f);
71 | }
72 | }
73 |
74 | public Vector3f GLcolor
75 | {
76 | get { return glColor; }
77 | }
78 |
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/platformerGame/cPlayerInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using System.IO;
8 | using System.Xml;
9 | using System.Xml.Serialization;
10 |
11 |
12 | namespace platformerGame
13 | {
14 | public class cPlayerInfo
15 | {
16 | public float Time { get; set; }
17 | public string Level { get; set; }
18 |
19 | public cPlayerInfo()
20 | {
21 | Time = 0.0f;
22 | Level = "no-level";
23 | }
24 |
25 |
26 |
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/platformerGame/cSpriteState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace platformerGame
8 | {
9 | enum HorizontalFacing
10 | {
11 | FACING_LEFT = 2,
12 | FACING_RIGHT
13 | };
14 |
15 | enum MotionType
16 | {
17 | STAND = 1,
18 | WALK,
19 | JUMP,
20 | FALL,
21 | LIE
22 | };
23 |
24 | class cSpriteState
25 | {
26 | private MotionType motionType;
27 | private HorizontalFacing horizontalFacing;
28 |
29 | public HorizontalFacing HorizontalFacing
30 | {
31 | get { return horizontalFacing; }
32 | set { horizontalFacing = value; }
33 | }
34 |
35 | public MotionType MotionType
36 | {
37 | get { return motionType; }
38 | set { motionType = value; }
39 | }
40 | public cSpriteState(MotionType motion, HorizontalFacing h_facing)
41 | {
42 | motionType = motion;
43 | horizontalFacing = h_facing;
44 | }
45 |
46 | public cSpriteState ShallowCopy()
47 | {
48 | return (cSpriteState)this.MemberwiseClone();
49 | }
50 | public static bool operator ==(cSpriteState a, cSpriteState b)
51 | {
52 | return (a.MotionType == b.MotionType && a.HorizontalFacing == b.HorizontalFacing);
53 | }
54 |
55 | public static bool operator !=(cSpriteState a, cSpriteState b)
56 | {
57 | return (a.MotionType != b.MotionType || a.HorizontalFacing != b.HorizontalFacing);
58 | }
59 |
60 | public static bool operator <(cSpriteState a, cSpriteState b)
61 | {
62 | if (a.MotionType != b.MotionType)
63 | {
64 | return a.MotionType < b.MotionType;
65 | }
66 |
67 | if (a.HorizontalFacing != b.HorizontalFacing)
68 | {
69 | return a.HorizontalFacing < b.HorizontalFacing;
70 | }
71 |
72 | return false;
73 | }
74 |
75 | public static bool operator >(cSpriteState a, cSpriteState b)
76 | {
77 | if (a.MotionType != b.MotionType)
78 | {
79 | return a.MotionType > b.MotionType;
80 | }
81 |
82 | if (a.HorizontalFacing != b.HorizontalFacing)
83 | {
84 | return a.HorizontalFacing > b.HorizontalFacing;
85 | }
86 |
87 | return false;
88 | }
89 |
90 | public override bool Equals(object obj)
91 | {
92 | cSpriteState other = (cSpriteState)obj;
93 | return (this.MotionType == other.MotionType && this.HorizontalFacing == other.HorizontalFacing);
94 | }
95 |
96 | public override int GetHashCode()
97 | {
98 | return (int)motionType ^ (int)horizontalFacing;
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/platformerGame/cSpriteStateController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using SFML.Graphics;
7 | using SFML.System;
8 | using platformerGame.Utilities;
9 |
10 | namespace platformerGame
11 | {
12 | class cSpriteStateController
13 | {
14 | Dictionary m_SpriteStates;
15 |
16 | cSpriteState m_PrevState;
17 | cSpriteState m_CurrentState;
18 |
19 | cAnimation m_pCurrentAnim;
20 |
21 | public cSpriteStateController()
22 | {
23 | m_SpriteStates = new Dictionary();
24 | m_pCurrentAnim = null;
25 | }
26 |
27 | public void AddAnimState_by_Full_Texture( cSpriteState state_type,
28 | Texture texture,
29 | int a_frame_width,
30 | int a_frame_height,
31 | int num_columns_of_frames,
32 | int num_rows_of_frames,
33 | uint frame_time )
34 | {
35 | cAnimation temp = new cAnimation(texture, new MyIntRect());
36 | //temp.SetSpriteSheet(texture);
37 |
38 | for (int y = 0; y < num_rows_of_frames; y++)
39 | {
40 | for (int x = 0; x < num_columns_of_frames; x++)
41 | {
42 | temp.AddFrame(new MyIntRect(x * a_frame_width,
43 | y * a_frame_height,
44 | a_frame_width,
45 | a_frame_height));
46 | }
47 | }
48 |
49 | temp.SetFrameTime(frame_time);
50 | temp.SetStartFrame(0);
51 |
52 | //KeyValuePair state_pair = new KeyValuePair(state_type, temp);
53 |
54 | m_SpriteStates.Add(state_type, temp);
55 | }
56 |
57 | public void AddAnimState(cSpriteState state_type,
58 | Texture texture,
59 | int frame_width,
60 | int frame_height,
61 | int start_frame_column, //x
62 | int start_frame_row, //y
63 | uint anim_start_frame,
64 | int num_frames,
65 | uint frame_time, // in ms
66 | MyIntRect view_rect,
67 | bool flip_vertically = false,
68 | bool flip_horizontally = false)
69 | {
70 | if(view_rect.Width == 0 && view_rect.Height == 0)
71 | {
72 | view_rect.Width = frame_width;
73 | view_rect.Height = frame_height;
74 | }
75 |
76 | cAnimation anim = new cAnimation(texture, view_rect);
77 | anim.AnimData.Repeat = true;
78 |
79 | anim.FlipHorizontally = flip_horizontally;
80 | anim.FlipVertically = flip_vertically;
81 | //anim.SetSpriteSheet(texture);
82 |
83 | //float a_frame_width = texture.getSize().x / max_frames;
84 | //float a_frame_height = texture.getSize().y;
85 |
86 | for (int x = 0; x < num_frames; ++x)
87 | {
88 | anim.AddFrame(new MyIntRect((start_frame_column + x) * frame_width,
89 | start_frame_row * frame_height,
90 | frame_width,
91 | frame_height));
92 | }
93 |
94 | anim.SetFrameTime(frame_time);
95 | anim.SetStartFrame(anim_start_frame);
96 |
97 | //std::pair state_pair = std::pair(state_type, anim);
98 |
99 | m_SpriteStates.Add(state_type, anim);
100 | }
101 |
102 | public void ChangeState(cSpriteState state_type)
103 | {
104 | m_CurrentState = state_type;
105 |
106 | m_pCurrentAnim = m_SpriteStates[state_type];
107 | }
108 |
109 | public cSpriteState getCurrentState()
110 | {
111 | return m_CurrentState;
112 | }
113 | public void Update(cSpriteState new_sprite_state)
114 | {
115 | //m_PrevState = m_CurrentState;
116 |
117 | m_CurrentState = new_sprite_state;
118 | m_pCurrentAnim = m_SpriteStates[m_CurrentState];
119 |
120 | //if(m_PrevState != m_CurrentState)
121 | //{
122 | // m_pCurrentAnim = &m_SpriteStates[m_CurrentState];
123 | //}
124 |
125 |
126 | m_pCurrentAnim.Update();
127 | }
128 |
129 | public void Clear()
130 | {
131 |
132 | foreach(cAnimation a in m_SpriteStates.Values)
133 | {
134 | a.Clear();
135 | }
136 |
137 | m_SpriteStates.Clear();
138 | }
139 |
140 | public void Render(RenderTarget destination, Vector2f pos)
141 | {
142 | m_pCurrentAnim.Render(destination, pos);
143 | }
144 |
145 | cAnimation GetCurrentAnimation()
146 | {
147 | return m_pCurrentAnim;
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/platformerGame/cWaterBlock.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Window;
8 | using SFML.System;
9 | using SFML.Graphics;
10 |
11 | using platformerGame.Utilities;
12 |
13 | namespace platformerGame
14 | {
15 | class cWaterNode
16 | {
17 | public Vector2f startPosition;
18 | public Vector2f position;
19 | public Vector2f lastPosition;
20 | public Vector2f velocity;
21 | public Vector2f acceleration;
22 | public Vector2f force;
23 |
24 | //private float factor;
25 |
26 | const float MAX_FORCE = 500.0f;
27 | const float MAX_VELOCITY = 4500.0f;
28 | float SPEED = 0.0f;
29 | public cWaterNode(Vector2f pos, float start_Y)
30 | {
31 | position = pos;
32 | lastPosition = position;
33 | startPosition = new Vector2f(pos.X, start_Y);
34 | //Random r = new Random();
35 | /* factor = (float)random.Next(-10, 10);*/
36 | velocity = new Vector2f(0.0f, 0.0f);
37 | force = new Vector2f();
38 | acceleration = new Vector2f();
39 |
40 | SPEED = AppRandom.GetRandomNumber(40, 300);
41 |
42 |
43 | }
44 |
45 | public void Update(float step_time)
46 | {
47 | force.Y = (startPosition.Y - position.Y) * SPEED;
48 | //cAppMath.Vec2Truncate(ref force, MAX_FORCE);
49 |
50 | acceleration.Y = force.Y * step_time;
51 | velocity.Y += acceleration.Y * step_time;
52 |
53 | AppMath.Vec2Truncate(ref velocity, MAX_VELOCITY);
54 |
55 | lastPosition = position;
56 |
57 | position.Y += velocity.Y * step_time; // * factor;
58 |
59 | force.Y = 0.0f;
60 | }
61 | }
62 |
63 | class cWaterBlock
64 | {
65 | AABB area;
66 | VertexArray vertices;
67 |
68 | const int MAX_OFFSET_Y = 4; //4
69 | const int MIN_OFFSET_Y = -3; //-3
70 |
71 | int DIVISION = 6;
72 |
73 | float unitLength;
74 |
75 | RenderStates rs = new RenderStates(BlendMode.Alpha);
76 |
77 | List waterNodes;
78 |
79 | public cWaterBlock()
80 | {
81 |
82 | vertices = new VertexArray(PrimitiveType.TrianglesStrip);
83 |
84 | waterNodes = new List();
85 |
86 | }
87 |
88 | public cWaterBlock(AABB area)
89 | {
90 | this.area = area.ShallowCopy();
91 |
92 | int divider = Constants.TILE_SIZE; // / 2
93 | DIVISION = (int)(this.area.dims.X / divider);
94 | unitLength = divider; // this.area.dims.X / (float)DIVISION;
95 |
96 | vertices = new VertexArray(PrimitiveType.TrianglesStrip);
97 |
98 | waterNodes = new List();
99 |
100 | Init();
101 | }
102 |
103 | public void Init()
104 | {
105 | vertices.Clear();
106 |
107 | //Color col = new Color(0, 140, 186); //a víz felső színe new Color(239,28,57);
108 | //Color col2 = new Color(20, 92, 147); // alsó színe new Color(217,37,50);
109 |
110 | //Color col = new Color(239,28,57);
111 | //Color col2 = new Color(217,37,50);
112 |
113 | Color col = new Color(15,151,219);
114 | Color col2 = new Color(11,115,163);
115 |
116 | int bottomY = (int)area.rightBottom.Y;
117 |
118 | Vector2f[] points = new Vector2f[DIVISION + 1];
119 |
120 |
121 | points[0] = new Vector2f(area.topLeft.X, area.topLeft.Y);
122 | points[DIVISION] = new Vector2f(area.rightBottom.X, area.topLeft.Y);
123 |
124 | for (int i = 1; i < points.Length-1; i++)
125 | {
126 | int add = AppRandom.GetRandomNumber(MIN_OFFSET_Y, MAX_OFFSET_Y);
127 | points[i] = new Vector2f(area.topLeft.X + i * unitLength, area.topLeft.Y + add);
128 | }
129 |
130 | vertices.Append(new Vertex(points[0], col));
131 |
132 | //mindig kettőt adunk hozzá: az alsót és a következő felsőt
133 | for (int i = 0; i < points.Length-1; i++)
134 | {
135 | //bottom
136 | vertices.Append(new Vertex(new Vector2f(points[i].X, bottomY), col2) );
137 |
138 | //következő
139 | vertices.Append(new Vertex(points[i+1], col));
140 |
141 | //Itt adunk hozzá egy waternode-ot
142 | waterNodes.Add(new cWaterNode(points[i + 1], area.topLeft.Y));
143 | }
144 |
145 | vertices.Append(new Vertex(new Vector2f(area.rightBottom.X, bottomY), col2));
146 | }
147 | public void Update(float step_time)
148 | {
149 | uint vIndex = 0;
150 | uint i = 0;
151 |
152 | do
153 | {
154 | waterNodes[(int)i].Update(step_time * 1.75f);
155 |
156 | //csak a felső csatlakozó vertexeket akarjuk mozgatni, így azokkal foglalkozunk
157 | vIndex = 2 + (i * 2);
158 |
159 | Vector2f vpoint = vertices[vIndex].Position;
160 | vpoint.Y = waterNodes[(int)i].position.Y;
161 |
162 | Vertex vert = vertices[vIndex];
163 | vert.Position = vpoint;
164 | vertices[vIndex] = vert;
165 |
166 | i++;
167 |
168 | }
169 | while (i < waterNodes.Count-1 && vIndex < vertices.VertexCount);
170 | }
171 |
172 | public AABB Area
173 | {
174 | get { return area; }
175 | }
176 | public void Render(RenderTarget destination)
177 | {
178 |
179 | destination.Draw(vertices, rs);
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/platformerGame/constants.json:
--------------------------------------------------------------------------------
1 | {
2 | "player-walk-speed": 250.0,
3 | "monster-walk-speed": 250.0,
4 | "player-max-walk-speed": 150.0,
5 | "monster-max-walk-speed": 90.0,
6 | "ground-slowdown-factor": 0.6,
7 | "air-slowdown-factor": 0.95,
8 | "jump-speed": 300.0,
9 | "max-Y-speed": 400.0,
10 | "gravity": 881.25,
11 | "jump-gravity": 460,
12 | "bullet-hit-force": 1000,
13 | "bullet-start-speed": 900,
14 | "default-weapon-firing-frequency": 12,
15 | "friction": 0.1,
16 | "restitution": 0.5,
17 | "glue": 0.001,
18 | "character-frame-width": 32,
19 | "character-frame-height": 32,
20 | "player-texture-name": "player1_char_set",
21 | "monster-texture-name": "monster1_char_set",
22 | "monster-max-health": 12,
23 | "character-collision-rect": {
24 | "Left": 10,
25 | "Top": 0,
26 | "Width": 22,
27 | "Height": 32
28 | },
29 | "character-view-rect": {
30 | "Left": 5,
31 | "Top": 0,
32 | "Width": 27,
33 | "Height": 32
34 | },
35 | "lightmap-color": {
36 | "R": 10,
37 | "G": 10,
38 | "B": 10,
39 | "A": 255
40 | },
41 | "background-color": {
42 | "R": 255,
43 | "G": 255,
44 | "B": 255,
45 | "A": 255
46 | }
47 | }
--------------------------------------------------------------------------------
/platformerGame/sfLine.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using SFML.Graphics;
8 | using SFML.System;
9 |
10 | namespace platformerGame
11 | {
12 | class sfLine : Drawable
13 | {
14 |
15 | private VertexArray vertices;
16 | //private float thickness;
17 | //private Color color;
18 | public sfLine(Vector2f point1, Vector2f point2, Color color, float thickness)
19 | {
20 | Vector2f direction = point2 - point1;
21 | Vector2f unitDirection = direction / (float)Math.Sqrt(direction.X * direction.X + direction.Y * direction.Y);
22 | Vector2f unitPerpendicular = new Vector2f(-unitDirection.Y, unitDirection.X);
23 |
24 | Vector2f offset = (thickness / 2.0f) * unitPerpendicular;
25 | vertices = new VertexArray(PrimitiveType.Quads);
26 | vertices.Append(new Vertex(point1 + offset, color));
27 | vertices.Append(new Vertex(point2 + offset, color));
28 | vertices.Append(new Vertex(point2 - offset, color));
29 | vertices.Append(new Vertex(point1 - offset, color));
30 | }
31 |
32 | public void Draw(RenderTarget target, RenderStates states)
33 | {
34 | target.Draw(vertices, states);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------