How to draw checkerpiece on the first n rows of a panel array with C#? - 2d

I have code that loops through a multidimensional array of panels to draw checkers on them. I have a problem implementing a control structure inside the loop to make sure the red checkers are only drawn on the first three rows, and then skip a row and draw black checkers on the remaining three rows. The code should maintain drawing the checkers on the panels with white background. I already have a loop that makes sure each panel with a white background has a checker on it, my problem is controlling the drawing to simulate a real life checkerboard...
Code
/*This code block contains the class for
the Checkerpiece object drawn on the panel
*/
public class Checkerpiece
{
//colors of the rounded pieces
Color color;
//specify where the checker is drawn
Panel target_square;
//specify the center of the circle
float center_x;
float center_y;
//specify the radius of the checker piece
float radii;
//fill the details inside the constructor
public Checkerpiece(Panel mypanel,Color color)
{
this.color = color;
this.target_square = mypanel;
this.center_x = mypanel.Width / 2;
this.center_y = mypanel.Height / 2;
this.radii = mypanel.Width / 2;
}
//this method draws the checkerpiece on the target panel
public void draw()
{
this.target_square.Paint += Target_square_Paint;
}
//this event will redraw the circles as needed
private void Target_square_Paint(object sender, PaintEventArgs e)
{
SolidBrush mybrush = new SolidBrush(color);
fillCircle(e.Graphics, mybrush, this.center_x, this.center_y,(float) radius);
}
//ellipse(checker) filler method
public static void fillCircle(Graphics g, Brush b, float centerX, float centerY, float radius)
{
g.FillEllipse(b, centerX - radius, centerY - radius,
radius + radius, radius + radius);
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Checkers
{
public partial class Form1 : Form
{
private Panel[,] _chessBoardPanels;
public Form1()
{
InitializeComponent();
}
}
/*Form1 class contains the loops that is responsible for drawing checkers on the board*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Checkers
{
public partial class Form1 : Form
{
//declare the panel array
private Panel[,] _chessBoardPanels;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//controls the size of a single square on the checkerboard
const int tileSize = 100;
//controls the number of squares on either side of the board
const int gridSize = 8;
//this is fr applying different colors to the board so the pattern is realized
var clr1 = Color.DarkGray;
var clr2 = Color.White;
// initialize the "chess board"
_chessBoardPanels = new Panel[gridSize, gridSize];
// double for loop to handle all rows and columns
for (var n = 0; n < gridSize; n++)
{
for (var m = 0; m < gridSize; m++)
{
// create new Panel control which will be one
// chess board tile
var newPanel = new Panel
{
Size = new Size(tileSize, tileSize),
Location = new Point(tileSize * n, tileSize * m)
};
// add to Form's Controls so that they show up
Controls.Add(newPanel);
// add to our 2d array of panels for future use
_chessBoardPanels[n, m] = newPanel;
// color the backgrounds
if (n % 2 == 0)
newPanel.BackColor = m % 2 != 0 ? clr1 : clr2;
else
newPanel.BackColor = m % 2 != 0 ? clr2 : clr1;
//draw a new checker piece if this is true
if (newPanel.BackColor == Color.White)
new CheckerPiece(newPanel,Color.Red).draw();
else
;
/*I need to add a loop to make sure the red checkers are drawn on the first three rows of each panel that has a white background*/
}
}
}
}
}

This is purely accidental but it works, I assumed the m stands for the columns, so I added this code to the draw logic and got what I wanted.
Code
//draw a new checker piece
if (newPanel.BackColor==Color.White &&m<=3)
new Checkerpiece(newPanel, Color.Red).draw();
;
if (newPanel.BackColor == Color.White && m > 4)
new Checkerpiece(newPanel, Color.Black).draw();
Output

Related

How to move and rotate game object in the direction of movement,How to rotate and move gameObject in the direction of movement

I'm doing a top-down shooter in Unity 2D and I'm currently trying to make a fire point, but when a character changes direction of movement, the fire point stays in the same position, but I want it to move and rotate. Sadly i have no idea how to do it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public Rigidbody2D rb;
Vector2 movement;
public Animator animator;
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
if(movement != Vector2.zero)
{
animator.SetFloat("Horizontal", movement.x);
}
animator.SetFloat("Speed", movement.sqrMagnitude);
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.deltaTime);
}
}
enter image description here
enter image description here
I want it to be like the first picture, but on the opposite side.
enter image description here
Something like this (I rotated it in photoshop)

AbsoluteLayout - Measure Label Height without placing label on UI

I am manually positioning labels in an AbsoluteLayout.
To do this correctly I would like to know the label height prior to placing it on the UI.
I have found this solution, but not without actually placing a label:
public double MeasureLabelHeight(string text, double width, double fontSize, double lineHeight, string fontFamily)
{
Label label = new Label();
label.WidthRequest = width;
label.FontSize = fontSize;
label.LineHeight = lineHeight;
label.FontFamily = fontFamily;
label.LineBreakMode = LineBreakMode.WordWrap;
label.Text = text;
MyAbsoluteLayout.Children.Add(view: label, position: new Point(0, Height)); //place out of sight
var sizeRequest = label.Measure(widthConstraint: width, heightConstraint: double.MaxValue, flags: MeasureFlags.None);
var labelTextHeight = sizeRequest.Request.Height;
MyAbsoluteLayout.Children.Remove(label);
return labelTextHeight;
}
This solution works on UWP, I still have to test it on Android and iOS.
I would like to improve on it though.
I am unable to get a correct Height value without actually placing it in the AbsoluteLayout (out of view) and am a bit worried about the overhead this probably causes with extra redraws.
I have found an old piece of code that seemingly uses native code to do this without actually placing it in the UI for iOS and Android. I'm wondering if there is a solution available that has no need for platform specific code.
Let Xamarin Forms measure them for you. Then you move them into position.
Do this by subclassing AbsoluteLayout, and adding an Action that a page can set, to be called when your layout has done LayoutChildren.
MyAbsoluteLayout.cs:
using System;
using Xamarin.Forms;
namespace XFSOAnswers
{
public class MyAbsoluteLayout : AbsoluteLayout
{
public MyAbsoluteLayout()
{
}
// Containing page will set this, to act on children during LayoutChildren.
public Action CustomLayoutAction { get; set; }
private bool _busy;
protected override void LayoutChildren(double x, double y, double width, double height)
{
// Avoid recursed layout calls as CustomLayoutAction moves children.
if (_busy)
return;
// Xamarin measures the children.
base.LayoutChildren(x, y, width, height);
_busy = true;
try
{
CustomLayoutAction?.Invoke();
}
finally
{
_busy = false;
// Layout again, to position the children, based on adjusted (x,y)s.
base.LayoutChildren(x, y, width, height);
}
}
}
}
Example usage - MyAbsoluteLayoutPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XFSOAnswers"
x:Class="XFSOAnswers.MyAbsoluteLayoutPage">
<ContentPage.Content>
<local:MyAbsoluteLayout x:Name="TheLayout">
<!-- Layout positions start (0,0). Adjusted later in PositionLabels. -->
<Label x:Name="Label1" Text="Welcome" />
<Label x:Name="Label2" Text="to" />
<Label x:Name="Label3" Text="Xamarin" />
<Label x:Name="Label4" Text=".Forms!" />
</local:MyAbsoluteLayout>
</ContentPage.Content>
</ContentPage>
MyAbsoluteLayoutPage.xaml.cs:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XFSOAnswers
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyAbsoluteLayoutPage : ContentPage
{
public MyAbsoluteLayoutPage()
{
InitializeComponent();
TheLayout.CustomLayoutAction = PositionLabels;
}
private void PositionLabels()
{
// Optional: Set breakpoint after these, to check that the bounds have values.
var bounds1 = Label1.Bounds;
var bounds2 = Label2.Bounds;
var bounds3 = Label3.Bounds;
var bounds4 = Label4.Bounds;
double x = 10;
double y = 20;
MoveAbsoluteChildTo(Label1, x, y);
x += Label1.Width;
y += Label1.Height;
MoveAbsoluteChildTo(Label2, x, y);
x += Label2.Width;
y += Label2.Height;
MoveAbsoluteChildTo(Label3, x, y);
x += Label3.Width;
y += Label3.Height;
MoveAbsoluteChildTo(Label4, x, y);
}
private static void MoveAbsoluteChildTo(View child, double x, double y)
{
AbsoluteLayout.SetLayoutBounds(child, new Rect(x, y, child.Width, child.Height));
}
}
}
Result:
See MyAbsoluteLayout and MyAbsoluteLayoutPage in ToolmakerSteve - repo XFormsSOAnswers.

How to create scrollview with fading edges in Xamarin forms? (Xamarin.ios)

I already have a custom renderer for scrollview that will create fading edges on Xamarin.android. So my problem now is that my renderer on iOS is not working.
Here is what I have:
using System;
using CoreAnimation;
using CoreGraphics;
using Foundation;
using Omregistrering.CustomControls;
using Omregistrering.iOS.Renderers;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(FadeScrollView), typeof(FadeScrollViewRenderer))]
namespace Omregistrering.iOS.Renderers
{
public class FadeScrollViewRenderer : ScrollViewRenderer
{
private CAGradientLayer gradientLayer;
private Double FadePercentage = 0.2;
private CGColor OpaqueColor = UIColor.Black.CGColor;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
//UpdateScrollView();
}
public override void ScrollRectToVisible(CGRect rect, bool animated)
{
base.ScrollRectToVisible(rect, animated);
}
private void UpdateScrollView()
{
// test with Bounces
ContentInset = new UIKit.UIEdgeInsets(0, 0, 0, 0);
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
ContentInsetAdjustmentBehavior = UIKit.UIScrollViewContentInsetAdjustmentBehavior.Never;
Bounces = false;
ScrollIndicatorInsets = new UIKit.UIEdgeInsets(0, 0, 0, 0);
}
private CGColor topOpacity()
{
var scrollViewHeight = Frame.Size.Height;
var scrollContentSizeHeight = ContentSize.Height;
var scrollOffset = ContentOffset.Y;
nfloat alpha = (scrollViewHeight >= scrollContentSizeHeight || scrollOffset <= 0) ? 1 : 0;
var color = new UIColor(white: 0, alpha: alpha);
return color.CGColor;
}
private CGColor bottomOpacity()
{
var scrollViewHeight = Frame.Size.Height;
var scrollContentSizeHeight = ContentSize.Height;
var scrollOffset = ContentOffset.Y;
nfloat alpha = (scrollViewHeight >= scrollContentSizeHeight || scrollOffset + scrollViewHeight >= scrollContentSizeHeight) ? 1 : 0;
var color = new UIColor(white: 0, alpha: alpha);
return color.CGColor;
}
public override void Draw(CGRect rect)
{
base.Draw(rect);
gradientLayer = new CAGradientLayer();
gradientLayer.Frame = rect;
var maskLayer = new CALayer();
gradientLayer.Colors = new CGColor[] { topOpacity(), OpaqueColor, OpaqueColor, bottomOpacity() };
gradientLayer.Locations = new NSNumber[] { 0, (NSNumber)FadePercentage, (NSNumber)(1 - FadePercentage), 1 };
maskLayer.AddSublayer(gradientLayer);
this.Layer.Mask = maskLayer;
}
}
}
And the result is this:
The renderer is fading at the bottom edge but is not updated in any way.The ideer is of course to have fading edges also when scrolling up and down.
Here a screenshot from android were we are in the middle of a scroll and both edges are fading, giving the illusion of more content.
Anyone who have a solution or has done this on Xamarin.ios
Thanks
I don't think you need renderers here.
You could use two png with gradient toward transparent, for each edge.
Then with ScrollView.Scrolled event, you can know if you reached the top or the bottom of the scroll view.
Doing so, you can set the opacity of the 2 images according to the distance from the edge.
In the following example, we'll consider only bottom:
private void OnScrolled(object sender, ScrolledEventArgs e)
{
MyScrollView scrollView = sender as MyScrollView;
double scrollingSpace = scrollView.ContentSize.Height - scrollView.Height;
MyBottomImage.Opacity = 1 - e.ScrollY/scrollingSpace;
}
I hope you get the idea :)

Use AS3 to write IOS like slide up menu

In an AS3 mobile App, I would like to have a menu of buttons or icons that slides up from the bottom. Using a SlideViewTransition, I can get part of what I want.
var transition:SlideViewTransition = new SlideViewTransition();
transition.direction = ViewTransitionDirection.UP;
transition.mode = SlideViewTransitionMode.COVER;
view.navigator.pushView(ShareView, null, null, transition);
This works, but it does not do two things that I need to do.
1) I want the new transition to only go up 1/2 of the screen so that the top part of the screen displays the view underneath.
2) I want the new view that covers to be partially transparent. By setting the alpha of the incoming view's contentGroup background alpha, the new view is transparent as it comes in. But, once it covers the view underneath the view becomes opaque.
this.contentGroup.setStyle('backgroundAlpha', 0.5);
Does anyone have any ideas of how I would have a view slide up 1/2 way and be transparent? I have no idea where to start, view skinning?, or subclass transition?, or use something in flash namespace instead of a spark view.
I decided it would be simplest to just use the lower level ActionScript and do the animation myself using methods that are normally applied to a Sprite, but in this case use a VGroup so that I could add spark elements to it. The following is the base class I wrote.
public class SlideUpDialog extends VGroup {
private var pctHeight:Number;
private var stopHeight:Number;
private var vertIncrement:Number;
public function SlideUpDialog(pctHeight:Number) {
super();
this.pctHeight = pctHeight;
if (stage) {
addedToStageHandler();
} else {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
}
private function addedToStageHandler(event:Event=null) : void {
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
graphics.beginFill(0xEEEEEE, 0.8);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight * pctHeight);
graphics.endFill();
var bevel:BevelFilter = new BevelFilter(4, -45);
this.filters = [ bevel ];
x = 0;
y = stage.stageHeight;
stopHeight = y * (1 - pctHeight);
vertIncrement = y / 2 / 24 / 4;
}
public function open() : void {
addEventListener(Event.ENTER_FRAME, openFrameHandler);
}
private function openFrameHandler(event:Event) : void {
if (y > stopHeight) {
y -= vertIncrement;
} else {
removeEventListener(Event.ENTER_FRAME, openFrameHandler);
}
}
public function close() : void {
... the reverse of open
}
}

How can I animate a circle with PlayN?

This is a follow up to my last question:
How can I draw a circle to the screen with PlayN?
For my simple case, I want to programmatically create a single colored circle and move it across a 2-D plain (doesn't need to use box2d lib).
A real-world example would likely involve animating several circles. Two real-world examples for this case (sorry, I had to remove the links -- not enough karma!):
Browsmos for Chrome
Ants AI Challenge
It was suggested in response to my last question that I would want to use the ImmediateLayer class, so I am looking to understand how to properly incorporate this into my game loop.
Here's is my code sample:
public class SimpleCircleAnimation implements Game {
// Surface
private GroupLayer rootLayer;
private ImmediateLayer surface;
private Canvas canvas;
private Circle circle;
private CanvasImage circleImage;
#Override
public void init() {
// create root layer
rootLayer = graphics().rootLayer();
// a simple circle object
int circleX = 0; int circleY = 0;
int circleRadius = 20;
circle = new Circle(circleX, circleY, circleRadius);
// create an immediate layer and add to root layer
ImmediateLayer circleLayer = graphics().createImmediateLayer(new ImmediateLayer.Renderer() {
public void render (Surface surf) {
circleImage = graphics().createImage(circle.radius*2, circle.radius*2);
canvas = circleImage.canvas();
canvas.setFillColor(0xff0000eb);
canvas.fillCircle(circle.radius, circle.radius, circle.radius);
surf.drawImage(circleImage, circle.x, circle.y);
}
});
rootLayer.add(circleLayer);
}
#Override
public void paint(float alpha) {
}
#Override
public void update(float delta) {
// move circle
int newX = circle.x + 4; int newY = circle.y + 4;
circle.setPoint(newX, newY);
}
#Override
public int updateRate() {
return 25;
}
}
This successfully moves the circle diagonally down the screen from left to right. A couple questions:
Is this implemented properly?
In the case of multiple animated circles, is the idea with ImmediateLayer that you would create a circle image for each circle within the Renderer callback? Or would you perhaps create an Immediate Layer for each circle and add those to the root layer?
I would not use ImmediateLayer wiht render (Surface surf) adapter. Here u have, inside the render method creation of an image
circleImage = graphics().createImage(circle.radius*2, circle.radius*2);
just put this in the paint method
surf.drawImage(circleImage, circle.x, circle.y);
using the normal layer and u should be fine
Painting is done in paint method, and do not put calculations there
Update is for calculations, and physics oriented stuff
I discovered a detailed practical example of ImmediateLayer usage in the Cute Game source within the PlayN Samples:
CuteGame.java (code.google.com)

Resources