Click here to Skip to main content
15,609,498 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    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;
        }
    }
}
Posted
Comments
Gerry Schmitz 5-Dec-22 10:26am    
If you want to test for "2 keypresses" at the same time, I suggest you add a "Shift" or a "Ctrl" (i.e. key modifiers) to expand the meaning of a given key. When you test a given key, you can then also test for Shift down, for example.

https://stackoverflow.com/questions/5750722/how-to-detect-modifier-key-states-in-wpf

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900