错误发生在 graphics.Clear(Color.FromArgb(18, 18, 18)) 上,如果删除此行,则在 GridForm KeyDown() 中调用了 MoveRaycastObject() 方法,错误将发生在 DrawScene 的此行:graphics.DrawLine(grid_pen, 1, 1, 1, grid.size_y * grid.size_of_point); (相同的错误)很明显,有某个错误导致了这些错误
形式:
namespace Raycasting
{
public partial class GridForm : Form
{
Scene scene;
public GridForm()
{
InitializeComponent();
}
private void GridForm_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
scene = new Scene(graphics, new Grid());
scene.DrawScene();
}
private void GridForm_KeyDown(object sender, KeyEventArgs e)
{
if (keyToIndex.ContainsKey(e.KeyCode))
{
if(scene.raycastObjects.Count > keyToIndex[e.KeyCode])
{
scene.SwitchCurrentRaycastObject(keyToIndex[e.KeyCode]);
}
}
int hor = GetAxis(e, Keys.A, Keys.D);
int ver = GetAxis(e, Keys.W, Keys.S);
if(hor !=0 || ver != 0) scene.MoveRaycastObject(hor, ver);
}
private int GetAxis(KeyEventArgs e,Keys first_direction, Keys second_direction)
{
if (e.KeyCode == first_direction) return -1;
else if (e.KeyCode == second_direction) return 1;
return 0;
}
Dictionary<Keys, int> keyToIndex = new Dictionary<Keys, int>()
{
{Keys.D1,0},{Keys.D2,1},{Keys.D3,2},{Keys.D4,3},
{Keys.D5,4},{Keys.D6,5},{Keys.D7,6},{Keys.D8,7},{Keys.D9,8}
};
}
}
场景:
using System.Drawing;
namespace Raycasting
{
internal class Scene
{
public List<RaycastObject> raycastObjects { get; private set; }
private Graphics graphics;
private Brush raycastObject_brush;
private Pen grid_pen;
private Map map;
private Grid grid;
public int currentRaycastObject { get; private set; } = 0;
public Scene(Graphics graphics, Grid grid, Pen grid_pen = null, Brush raycastObject_brush = null, params RaycastObject[] raycastObjects)
{
this.grid = grid;
this.graphics = graphics;
this.raycastObjects = (raycastObjects.Length==0) ? new List<RaycastObject>
{
new RaycastObject(),
new RaycastObject(new Point(40, 40))
} : raycastObjects.ToList();
this.grid_pen ??= new Pen(Color.FromArgb(245, 193, 5));
this.raycastObject_brush ??= new SolidBrush(Color.FromArgb(87, 255, 36));
map = new Map(grid.size_of_point, grid.size_x, grid.size_y);
}
public void DrawScene()
{
DrawGrid();
DrawRaycastObjects();
}
public void DrawGrid()
{
//Additional line , if you have some troubles with monitor
graphics.DrawLine(grid_pen, 1, 1, 1, grid.size_y * grid.size_of_point);
for(int i = 0; i <= grid.size_x; i++)
{
graphics.DrawLine(grid_pen, 0, i * grid.size_of_point, grid.size_x * grid.size_of_point, i * grid.size_of_point);
}
for (int i = 0; i <= grid.size_y; i++)
{
graphics.DrawLine(grid_pen, i * grid.size_of_point,0, i * grid.size_of_point, grid.size_y * grid.size_of_point);
}
}
public bool AddRaycastObject(RaycastObject raycastObject)
{
if(raycastObjects.Contains(raycastObject))
{
return false;
}
raycastObjects.Add(raycastObject);
return true;
}
public void DrawRaycastObjects()
{
foreach(var ro in raycastObjects)
{
DrawRaycastObject(ro);
}
}
public void DrawRaycastObject(RaycastObject raycastObject)
{
graphics.FillEllipse(raycastObject_brush, raycastObject.position.X, raycastObject.position.Y, raycastObject.size.X,raycastObject.size.Y);
}
public void MoveRaycastObject(int horizontal_axis, int vertical_axis)
{
Point current_pos_on_map = new Point(raycastObjects[currentRaycastObject].position.X /map.size_x, raycastObjects[currentRaycastObject].position.Y /map.size_y);
Point new_pos_on_map = new Point((current_pos_on_map.X/map.size_x) + horizontal_axis, (current_pos_on_map.Y/map.size_y) + vertical_axis);
new_pos_on_map.X = Math.Clamp(current_pos_on_map.X, 0, map.size_x);
new_pos_on_map.Y = Math.Clamp(current_pos_on_map.Y, 0, map.size_y);
map.MoveRaycastObjectOnMap(current_pos_on_map, new_pos_on_map);
raycastObjects[currentRaycastObject].position = new_pos_on_map;
graphics.Clear(Color.FromArgb(18, 18, 18));
DrawScene();
}
public void SwitchCurrentRaycastObject(int next_raycastObject)
{
currentRaycastObject = next_raycastObject;
}
}
internal class Grid
{
public int size_of_point { get; private set; }
public int size_x { get; private set; }
public int size_y { get; private set; }
public Grid(int size_of_point = 20,int size_x = 20,int size_y = 20)
{
this.size_of_point = size_of_point;
this.size_x = size_x;
this.size_y = size_y;
}
}
}
地图:
namespace Raycasting
{
class Map
{
public int size_of_point { get; private set; }
public int size_x { get; private set; }
public int size_y { get; private set; }
private char[,] map;
private char filling_char { get; set; }
private char block_char { get; set; }
private char raycast_object_char { get; set; }
public Map(int size_of_point,int size_x,int size_y,char filling_char = '.',char block_char = '#', char raycast_object_char = 'O')
{
this.size_of_point = size_of_point;
this.size_x = size_x;
this.size_y = size_y;
this.filling_char = filling_char;
this.block_char = block_char;
this.raycast_object_char = raycast_object_char;
ClearMap();
}
private void ClearMap()
{
map = new char[size_x, size_y];
for (int x =0;x < size_x;x++)
{
for (int y = 0; y < size_y; y++)
{
map[x, y] = filling_char;
}
}
}
public void SetBlock(Point position)
{
map[position.X, position.Y] = block_char;
}
public void MoveRaycastObjectOnMap(Point formerPos,Point new_position)
{
RemoveRaycastObjectFromMap(formerPos);
SetRaycastObjectOnMap(new_position);
}
public void SetRaycastObjectOnMap(Point position)
{
map[position.X, position.Y] = raycast_object_char;
}
public void RemoveRaycastObjectFromMap(Point position)
{
map[position.X, position.Y] = filling_char;
}
}
}
射线投射对象:
namespace Raycasting
{
class RaycastObject
{
public Point position { get; set; }
public Point size { get;private set; }
public RaycastObject()
{
position = new Point(0, 0);
size = new Point(20, 20);
}
public RaycastObject(Point position)
{
this.position = position;
size = new Point(20, 20);
}
public RaycastObject(Point position, Point size)
{
this.position = position;
this.size = size;
}
}
}