Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
coderZsq committed Sep 11, 2020
1 parent 4e744d0 commit ff16165
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 208 deletions.
12 changes: 6 additions & 6 deletions SQNumber/SQNumber.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
1461A83A250BC1BC006CE5FE /* SQSceneView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1461A839250BC1BC006CE5FE /* SQSceneView.m */; };
14EABDA3250B57520091F19B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14EABDA2250B57520091F19B /* AppDelegate.m */; };
14EABDA6250B57520091F19B /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14EABDA5250B57520091F19B /* SceneDelegate.m */; };
14EABDA9250B57520091F19B /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 14EABDA8250B57520091F19B /* ViewController.m */; };
Expand All @@ -15,10 +16,11 @@
14EABDB1250B57530091F19B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14EABDAF250B57530091F19B /* LaunchScreen.storyboard */; };
14EABDB4250B57530091F19B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 14EABDB3250B57530091F19B /* main.m */; };
14EABDC1250B60A10091F19B /* SQSpriteView.m in Sources */ = {isa = PBXBuildFile; fileRef = 14EABDC0250B60A10091F19B /* SQSpriteView.m */; };
14EABE11250BB6FA0091F19B /* SQTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 14EABE0F250BB6F90091F19B /* SQTimer.m */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
1461A838250BC1BC006CE5FE /* SQSceneView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQSceneView.h; sourceTree = "<group>"; };
1461A839250BC1BC006CE5FE /* SQSceneView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SQSceneView.m; sourceTree = "<group>"; };
14EABD9E250B57520091F19B /* SQNumber.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SQNumber.app; sourceTree = BUILT_PRODUCTS_DIR; };
14EABDA1250B57520091F19B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
14EABDA2250B57520091F19B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
Expand All @@ -33,8 +35,6 @@
14EABDB3250B57530091F19B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
14EABDBF250B60A10091F19B /* SQSpriteView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQSpriteView.h; sourceTree = "<group>"; };
14EABDC0250B60A10091F19B /* SQSpriteView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQSpriteView.m; sourceTree = "<group>"; };
14EABE0F250BB6F90091F19B /* SQTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SQTimer.m; sourceTree = "<group>"; };
14EABE10250BB6FA0091F19B /* SQTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQTimer.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -73,10 +73,10 @@
14EABDA5250B57520091F19B /* SceneDelegate.m */,
14EABDA7250B57520091F19B /* ViewController.h */,
14EABDA8250B57520091F19B /* ViewController.m */,
1461A838250BC1BC006CE5FE /* SQSceneView.h */,
1461A839250BC1BC006CE5FE /* SQSceneView.m */,
14EABDBF250B60A10091F19B /* SQSpriteView.h */,
14EABDC0250B60A10091F19B /* SQSpriteView.m */,
14EABE10250BB6FA0091F19B /* SQTimer.h */,
14EABE0F250BB6F90091F19B /* SQTimer.m */,
14EABDAA250B57520091F19B /* Main.storyboard */,
14EABDAD250B57530091F19B /* Assets.xcassets */,
14EABDAF250B57530091F19B /* LaunchScreen.storyboard */,
Expand Down Expand Up @@ -158,8 +158,8 @@
files = (
14EABDA9250B57520091F19B /* ViewController.m in Sources */,
14EABDA3250B57520091F19B /* AppDelegate.m in Sources */,
1461A83A250BC1BC006CE5FE /* SQSceneView.m in Sources */,
14EABDB4250B57530091F19B /* main.m in Sources */,
14EABE11250BB6FA0091F19B /* SQTimer.m in Sources */,
14EABDA6250B57520091F19B /* SceneDelegate.m in Sources */,
14EABDC1250B60A10091F19B /* SQSpriteView.m in Sources */,
);
Expand Down
19 changes: 19 additions & 0 deletions SQNumber/SQNumber/SQScene.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// SQScene.h
// SQNumber
//
// Created by 朱双泉 on 2020/9/11.
// Copyright © 2020 朱双泉. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SQSceneView : NSObject

- (instancetype)initWithCapacity:(NSUInteger)capacity;

@end

NS_ASSUME_NONNULL_END
85 changes: 85 additions & 0 deletions SQNumber/SQNumber/SQScene.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// SQScene.m
// SQNumber
//
// Created by 朱双泉 on 2020/9/11.
// Copyright © 2020 朱双泉. All rights reserved.
//

#import "SQSceneView.h"
#import <UIKit/UIKit.h>

@implementation SQSceneView

- (instancetype)initWithCapacity:(NSUInteger)capacity {
self = [super init];
if (self) {
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:capacity];

UIView *containerView = [UIView new];
CGFloat containerViewW = self.view.bounds.size.width * 0.9;
CGFloat containerViewH = containerViewW * 0.2;
CGFloat containerViewX = (self.view.bounds.size.width - containerViewW) * 0.5;
CGFloat containerViewY = (self.view.bounds.size.height - containerViewH) * 0.5;
containerView.frame = CGRectMake(containerViewX, containerViewY, containerViewW, containerViewH);
[self.view addSubview:containerView];

CGFloat innerViewW = containerViewH - 20;
CGFloat innerViewH = innerViewW;
CGFloat innerViewY = (containerViewH - innerViewH) * 0.5;
CGFloat innerViewS = (containerViewW - (innerViewW * capacity)) / (capacity + 1);
CGFloat movableViewW = innerViewW - 20;
CGFloat movableViewH = movableViewW;
for (NSInteger i = 0; i < capacity; i++) {
UIView *innerView = [UIView new];
CGFloat innerViewX = innerViewS + (i * (innerViewW + innerViewS));
innerView.backgroundColor = [UIColor lightGrayColor];
innerView.frame = CGRectMake(innerViewX, innerViewY, innerViewW, innerViewH);
[containerView addSubview:innerView];

UILabel *innerLabel = [UILabel new];
innerLabel.text = @(i + 1).stringValue;
innerLabel.textAlignment = NSTextAlignmentCenter;
innerLabel.font = [UIFont boldSystemFontOfSize:120];
innerLabel.frame = innerView.bounds;
[innerView addSubview:innerLabel];

SQSpriteView *spriteView = [SQSpriteView new];
spriteView.matchRect = [innerView.superview convertRect:innerView.frame toView:self.view];
spriteView.backgroundColor = [UIColor systemGreenColor];
NSString *address = [NSString stringWithFormat:@"%p", spriteView];
dict[address] = @(NO);

spriteView.matching = ^(SQSpriteView *matchView) {
if (matchView.isMatch) {
matchView.matched = YES;
dict[address] = @(YES);
}
BOOL successed = YES;
for (NSNumber *num in dict.allValues) {
if (!num.boolValue) {
successed = NO;
}
}
if (successed) {
NSLog(@"游戏通关");
}
};

CGFloat movableViewX = arc4random() % (int)(self.view.bounds.size.width - movableViewW);
CGFloat movableViewY = arc4random() % (int)(self.view.bounds.size.height - movableViewH);
spriteView.frame = CGRectMake(movableViewX, movableViewY, movableViewW, movableViewH);
[self.view addSubview:spriteView];

UILabel *movableLabel = [UILabel new];
movableLabel.text = innerLabel.text;
movableLabel.textAlignment = innerLabel.textAlignment;
movableLabel.font = innerLabel.font;
movableLabel.frame = spriteView.bounds;
[spriteView addSubview:movableLabel];
}
}
return self;
}

@end
21 changes: 21 additions & 0 deletions SQNumber/SQNumber/SQSceneView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// SQSceneView.h
// SQNumber
//
// Created by 朱双泉 on 2020/9/11.
// Copyright © 2020 朱双泉. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface SQSceneView : UIView

@property (nonatomic, assign) NSUInteger capacity;

- (void)renderToCanvas:(UIView *)superView;

@end

NS_ASSUME_NONNULL_END
84 changes: 84 additions & 0 deletions SQNumber/SQNumber/SQSceneView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// SQSceneView.m
// SQNumber
//
// Created by 朱双泉 on 2020/9/11.
// Copyright © 2020 朱双泉. All rights reserved.
//

#import "SQSceneView.h"
#import "SQSpriteView.h"

@implementation SQSceneView

- (void)renderToCanvas:(UIView *)superView {
[superView addSubview:self];

NSInteger capacity = self.capacity ? self.capacity : 3;
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:capacity];

UIView *containerView = [UIView new];
CGFloat containerViewW = self.bounds.size.width * 0.9;
CGFloat containerViewH = containerViewW * 0.2;
CGFloat containerViewX = (self.bounds.size.width - containerViewW) * 0.5;
CGFloat containerViewY = (self.bounds.size.height - containerViewH) * 0.5;
containerView.frame = CGRectMake(containerViewX, containerViewY, containerViewW, containerViewH);
[self addSubview:containerView];

CGFloat innerViewW = containerViewH - 20;
CGFloat innerViewH = innerViewW;
CGFloat innerViewY = (containerViewH - innerViewH) * 0.5;
CGFloat innerViewS = (containerViewW - (innerViewW * capacity)) / (capacity + 1);
CGFloat movableViewW = innerViewW - 20;
CGFloat movableViewH = movableViewW;
for (NSInteger i = 0; i < capacity; i++) {
UIView *innerView = [UIView new];
CGFloat innerViewX = innerViewS + (i * (innerViewW + innerViewS));
innerView.backgroundColor = [UIColor lightGrayColor];
innerView.frame = CGRectMake(innerViewX, innerViewY, innerViewW, innerViewH);
[containerView addSubview:innerView];

UILabel *innerLabel = [UILabel new];
innerLabel.text = @(i + 1).stringValue;
innerLabel.textAlignment = NSTextAlignmentCenter;
innerLabel.font = [UIFont boldSystemFontOfSize:120];
innerLabel.frame = innerView.bounds;
[innerView addSubview:innerLabel];

SQSpriteView *spriteView = [SQSpriteView new];
spriteView.matchRect = [innerView.superview convertRect:innerView.frame toView:self];
spriteView.backgroundColor = [UIColor systemGreenColor];
NSString *address = [NSString stringWithFormat:@"%p", spriteView];
dict[address] = @(NO);

spriteView.matching = ^(SQSpriteView *matchView) {
if (matchView.isMatch) {
matchView.matched = YES;
dict[address] = @(YES);
}
BOOL successed = YES;
for (NSNumber *num in dict.allValues) {
if (!num.boolValue) {
successed = NO;
}
}
if (successed) {
NSLog(@"游戏通关");
}
};

CGFloat movableViewX = arc4random() % (int)(self.bounds.size.width - movableViewW);
CGFloat movableViewY = arc4random() % (int)(self.bounds.size.height - movableViewH);
spriteView.frame = CGRectMake(movableViewX, movableViewY, movableViewW, movableViewH);
[self addSubview:spriteView];

UILabel *movableLabel = [UILabel new];
movableLabel.text = innerLabel.text;
movableLabel.textAlignment = innerLabel.textAlignment;
movableLabel.font = innerLabel.font;
movableLabel.frame = spriteView.bounds;
[spriteView addSubview:movableLabel];
}
}

@end
36 changes: 22 additions & 14 deletions SQNumber/SQNumber/SQSpriteView.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,34 @@
//

#import "SQSpriteView.h"
#import "SQTimer.h"

@interface SQSpriteView ()

@property (nonatomic, copy) NSString *directionTimerId;
@property (nonatomic, copy) NSString *frameTimerId;
@property (nonatomic, strong) NSTimer *directionTimer;
@property (nonatomic, strong) NSTimer *frameTimer;

@end

@implementation SQSpriteView

- (void)dealloc {
[self clearTimer];
}

- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self updateCoordinate];
[self performSelector:@selector(updateCoordinate)
withObject:nil afterDelay:(arc4random() % 3)];
}
return self;
}

- (void)clearTimer {
[self.directionTimer invalidate];
[self.frameTimer invalidate];
}

typedef NS_ENUM(NSUInteger, SQSpriteDirection) {
SQSpriteDirectionNone = 0,
SQSpriteDirectionUp,
Expand All @@ -39,11 +48,12 @@ typedef NS_ENUM(NSUInteger, SQSpriteDirection) {

- (void)updateCoordinate {
__block NSInteger direction = 0;
self.directionTimerId = [SQTimer execTask:^{

self.directionTimer = [NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {
direction = arc4random() % 9;
} start:0 interval:2 repeats:YES async:NO];
self.frameTimerId = [SQTimer execTask:^{
}];

self.frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.03 repeats:YES block:^(NSTimer * _Nonnull timer) {
CGRect frame = self.frame;
switch (direction) {
case SQSpriteDirectionNone:
Expand Down Expand Up @@ -91,12 +101,7 @@ - (void)updateCoordinate {
} else if (self.frame.origin.y + self.bounds.size.height + margin >= self.superview.bounds.size.height) {
direction = SQSpriteDirectionUp;
}
} start:0 interval:0.03 repeats:YES async:NO];
}

- (void)clearTimer {
[SQTimer cancelTask:self.directionTimerId];
[SQTimer cancelTask:self.frameTimerId];
}];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
Expand All @@ -105,6 +110,8 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

if (self.matched) return;

[self.superview bringSubviewToFront:self];

UITouch * touch = [touches anyObject];
CGPoint current = [touch locationInView:self];
CGPoint previous = [touch previousLocationInView:self];
Expand All @@ -128,6 +135,7 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

_match = CGRectContainsRect(self.matchRect, self.frame);
if (self.isMatch) {
[self.superview sendSubviewToBack:self];
[self clearTimer];
} else {
[self updateCoordinate];
Expand Down
32 changes: 0 additions & 32 deletions SQNumber/SQNumber/SQTimer.h

This file was deleted.

Loading

0 comments on commit ff16165

Please sign in to comment.