I want to program a 2D jump 'n' run like Super Mario Bros. in WPF. The code works so far, but the player-movement doesn't work like it should. I can't move when Mario is midair or when I am moving, i can't jump. I played around with Keyboard.IsKeyDown(e.Key), but there I loose all the momentum when I am trying to jump while I am moving. Is there any way to detect two keypresses at the same time?
Here would be my C# code:
What I have tried:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using static System.Net.Mime.MediaTypeNames;
namespace Endless_Runner_Base
{
public partial class MainWindow : Window
{
DispatcherTimer gameTimer = new DispatcherTimer();
Rect playerHitBox;
Rect groundHitBox;
Rect obstacleHitBox;
Rect goombaHitBox;
bool jumping;
int force = 20;
int speed = 5;
Random rnd = new Random();
bool gameOver;
double spriteIndex = 0;
ImageBrush playerSprite = new ImageBrush();
ImageBrush backgroundSprite = new ImageBrush();
ImageBrush obstacleSprite = new ImageBrush();
ImageBrush goombaSprite = new ImageBrush();
int[] obstaclePosition = { 320, 310, 300, 305, 315 };
int score = 0;
public MainWindow()
{
InitializeComponent();
myCanvas.Focus();
gameTimer.Tick += GameEngine;
gameTimer.Interval = TimeSpan.FromMilliseconds(20);
backgroundSprite.ImageSource = new BitmapImage(new Uri("C:\\Users\\jho\\Desktop\\Visual Projekte\\trunk\\Endless Runner Base\\Endless Runner Base\\images\\background.gif"));
background.Fill = backgroundSprite;
background2.Fill = backgroundSprite;
StartGame();
}
private void GameEngine(object? sender, EventArgs e)
{
if(Canvas.GetLeft(background) < -1024)
{
Canvas.SetLeft(background, Canvas.GetLeft(background2) + background2.Width);
}
if (Canvas.GetLeft(background2) < -1024)
{
Canvas.SetLeft(background2, Canvas.GetLeft(background) + background.Width);
}
Canvas.SetTop(player, Canvas.GetTop(player) + speed);
scoreText.Content = "Score: " + score;
playerHitBox = new Rect(Canvas.GetLeft(player), Canvas.GetTop(player), player.Width -15, player.Height);
obstacleHitBox = new Rect(Canvas.GetLeft(obstacle) +10, Canvas.GetTop(obstacle), obstacle.Width, obstacle.Height);
groundHitBox = new Rect(Canvas.GetLeft(ground), Canvas.GetTop(ground), ground.Width, ground.Height);
if(playerHitBox.IntersectsWith(groundHitBox))
{
speed = 0;
Canvas.SetTop(player, Canvas.GetTop(ground) - player.Height );
jumping= false;
spriteIndex += .5;
if(spriteIndex > 4)
{
spriteIndex= 1;
}
RunSprite(spriteIndex);
}
if(jumping == true)
{
speed = -9;
force -= 1;
}
else
{
speed = 12;
}
if (force < 0)
{
jumping= false;
}
if(Canvas.GetLeft(obstacle) < -50)
{
Canvas.SetLeft(obstacle, 950);
Canvas.SetTop(obstacle, obstaclePosition[rnd.Next(0, obstaclePosition.Length)]);
score += 1;
}
if (playerHitBox.IntersectsWith(goombaHitBox))
{
gameOver = true;
gameTimer.Stop();
}
if (gameOver == true)
{
obstacle.Stroke = Brushes.Black;
obstacle.StrokeThickness = 1;
player.Stroke = Brushes.Red;
player.StrokeThickness = 1;
scoreText.Content = "Score: " + score + " Press ENTER to play again!!";
}
else
{
player.StrokeThickness= 0;
obstacle.StrokeThickness= 0;
}
}
private void KeyIsDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && gameOver == true)
{
StartGame();
}
if(e.Key == Key.Left)
{
if (Keyboard.IsKeyDown(Key.Space))
{
Jump();
}
Canvas.SetLeft(background, Canvas.GetLeft(background) + 3);
Canvas.SetLeft(background2, Canvas.GetLeft(background2) + 3);
Canvas.SetLeft(obstacle, Canvas.GetLeft(obstacle) +12);
Canvas.SetLeft(Goomba, Canvas.GetLeft(Goomba) + 12);
}
else if(e.Key == Key.Right)
{
if (Keyboard.IsKeyDown(Key.Space))
{
Jump();
}
Canvas.SetLeft(background, Canvas.GetLeft(background) - 3);
Canvas.SetLeft(background2, Canvas.GetLeft(background2) - 3);
Canvas.SetLeft(obstacle, Canvas.GetLeft(obstacle) - 12);
Canvas.SetLeft(Goomba, Canvas.GetLeft(Goomba) - 12);
}
else if(e.Key == Key.Space)
{
if (Keyboard.IsKeyDown(Key.Left))
{
Canvas.SetLeft(background, Canvas.GetLeft(background) + 3);
Canvas.SetLeft(background2, Canvas.GetLeft(background2) + 3);
Canvas.SetLeft(obstacle, Canvas.GetLeft(obstacle) + 12);
Canvas.SetLeft(Goomba, Canvas.GetLeft(Goomba) + 12);
}
else if (Keyboard.IsKeyDown(Key.Right))
{
Canvas.SetLeft(background, Canvas.GetLeft(background) - 3);
Canvas.SetLeft(background2, Canvas.GetLeft(background2) - 3);
Canvas.SetLeft(obstacle, Canvas.GetLeft(obstacle) - 12);
Canvas.SetLeft(Goomba, Canvas.GetLeft(Goomba) - 12);
}
Jump();
}
}
private void Jump()
{
if (jumping == false && playerHitBox.IntersectsWith(groundHitBox))
{
jumping = true;
force = 15;
speed = -12;
playerSprite.ImageSource = new BitmapImage(new Uri("C:\\Users\\jho\\Desktop\\Visual Projekte\\trunk\\Endless Runner Base\\Endless Runner Base\\images\\pixil-frame-1.png"));
}
}
private void KeyIsUp(object sender, KeyEventArgs e)
{
}
private void StartGame()
{
Canvas.SetLeft(background, 0);
Canvas.SetLeft(background2, 1024);
Canvas.SetLeft(player, 110);
Canvas.SetTop(player, 140);
Canvas.SetLeft(obstacle, 950);
Canvas.SetTop (obstacle, 310);
Canvas.SetLeft(Goomba, 300);
Canvas.SetTop(Goomba, 310);
RunSprite(1);
goombaSprite.ImageSource = new BitmapImage(new Uri("C:\\Users\\jho\\Desktop\\vector-goomba-super-mario-bros-goomba-sprite-11563054676w6lknv0fmv.png"));
obstacleSprite.ImageSource = new BitmapImage(new Uri("C:\\Users\\jho\\Desktop\\Visual Projekte\\trunk\\Endless Runner Base\\Endless Runner Base\\images\\obstacle.png"));
obstacle.Fill = obstacleSprite;
Goomba.Fill= goombaSprite;
jumping = false;
gameOver= false;
score = 0;
scoreText.Content = "Score: " + score;
gameTimer.Start();
}
private void RunSprite(double i)
{
switch(i)
{
case 1:
playerSprite.ImageSource = new BitmapImage(new Uri("C:\\Users\\jho\\Desktop\\Visual Projekte\\trunk\\Endless Runner Base\\Endless Runner Base\\images\\pixil-frame-0.png"));
break;
case 2:
playerSprite.ImageSource = new BitmapImage(new Uri("C:\\Users\\jho\\Desktop\\Visual Projekte\\trunk\\Endless Runner Base\\Endless Runner Base\\images\\pixil-frame-3.png"));
break;
}
player.Fill = playerSprite;
}
}
}