首页 > 解决方案 > C# WPF 椭圆在矩形上弹跳

问题描述

我正在尝试为一个学校项目制作一个单人乒乓球游戏,但我不知道如何处理在矩形上弹跳的椭圆。正如您在 XAML 中看到的那样,它们都在画布内,我将留下我的代码,请我需要帮助,因为我被困在这一点上。我尝试了不同的方法,但我无法弄清楚,所以任何提示都会有所帮助!

<Window x:Class="PongSolo.Game"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PongSolo"
        mc:Ignorable="d"
        Title="Game" Height="450" Width="650" Closing="Game_Closing" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="5*"></RowDefinition>
        </Grid.RowDefinitions>
        <Border Name="superBorder" BorderBrush="Black" BorderThickness="10" Grid.Row="1">
            <Canvas Name="superCanvas">
                <Rectangle x:Name="superRect" Fill="Blue" Width="100" Height="15" Canvas.Bottom="0" Canvas.Left="0"/>
                <Ellipse x:Name="superElly" Fill="Purple" Width="20" Height="20" Grid.Row="1" Canvas.Top="0" Canvas.Left="0"/>
            </Canvas>
        </Border>
        <Label Content="Punteggio:" FontWeight="Bold" FontSize="20" Grid.Row="0"/>
        <Label Content="0" Name="scoreLabel" FontWeight="Bold" FontSize="20" Grid.Row="0" Margin="119,0,-119,0"/>
       
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace PongSolo
{
    /// <summary>
    /// Logica di interazione per Game.xaml
    /// </summary>
    public partial class Game : Window
    {
        SoundPlayer sound = new System.Media.SoundPlayer(Environment.CurrentDirectory+"/Resources/bgm_new.wav");
        DispatcherTimer playerDispatcher = new DispatcherTimer();
        DispatcherTimer ballDispatcher = new DispatcherTimer();

        int score = 0;

        double startxspeed = 4;
        double startyspeed = 4;
        public Game()
        {
            InitializeComponent();
            playerDispatcher.Interval = TimeSpan.FromMilliseconds(10);
            ballDispatcher.Interval = TimeSpan.FromMilliseconds(10);
            ballDispatcher.Tick += ballMovement;
            playerDispatcher.Tick += playerMovement;
            playerDispatcher.Start();
            ballDispatcher.Start();
        }

        private void ballMovement(object sender, EventArgs e)
        {
            double xspeed = Canvas.GetLeft(superElly) + startxspeed;
            double yspeed = Canvas.GetTop(superElly) + startyspeed;
        
               //Ball collision with rectangle
                if(/*bouncing statement*/)
                {
                    score++;
                    scoreLabel.Content = score.ToString();
                    startyspeed *= -1;
                }


            //up collision
            if (yspeed < (superCanvas.ActualHeight - (superElly.ActualHeight / 2)) && yspeed > 0)
                Canvas.SetTop(superElly, yspeed);
            else
            {
                startyspeed *= -1;
            }
                

            //down collision
            if(yspeed >= (superCanvas.ActualHeight - (superElly.ActualHeight/2)) && yspeed >0)
            {
                playerDispatcher.Stop();
                ballDispatcher.Stop();
            }

            //lateral collision
            if (xspeed < (superCanvas.ActualWidth - (superElly.ActualWidth / 2 + 10)) && xspeed > 0)
                Canvas.SetLeft(superElly, xspeed);
            else
            {
                startxspeed *= -1;
            }
               
        }

        private void playerMovement(object sender, EventArgs e)
        {
            double xvalue = Canvas.GetLeft(superRect) + 3;

            if (Keyboard.IsKeyDown(Key.Left))
            {
                if (!outOfBoundaries("left"))
                    MovePlayerLeft();
            }              
            if (Keyboard.IsKeyDown(Key.Right))
            {
                if (!outOfBoundaries("right"))
                    MovePlayerRight();
            }                   
        }

        public bool outOfBoundaries(string s)
        {
            bool is_out_of_boundaries = false;
            switch (s)
            {
                case "left":
                    {
                        if (Canvas.GetLeft(superRect) <= 0)
                            is_out_of_boundaries = true;
                        break;
                    }                 
                case "right":
                    {
                        if (Canvas.GetLeft(superRect) >= superCanvas.ActualWidth-superRect.Width)
                            is_out_of_boundaries = true;
                        break;
                    }
                    
                default:
                    break;
            }
            return is_out_of_boundaries;
        }

        private void MovePlayerRight()
        {
            Canvas.SetLeft(superRect, Canvas.GetLeft(superRect) + 5);
        }

        private void MovePlayerLeft()
        {
            Canvas.SetLeft(superRect, Canvas.GetLeft(superRect) - 5);
        }

        private void Game_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            App.Current.Shutdown();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.MinHeight = 300;
            this.MinWidth = 300;
            PlayMusic();
        }

        private void PlayMusic()
        {   
            sound.PlayLooping();
        }
    }
}

标签: c#wpf

解决方案


推荐阅读